5 * Postflight and shutdown code.
11 * The main Drush function.
13 * This function is still called by drush-launcher. It is no longer used by
16 function drush_main() {
17 require dirname(__DIR__) . '/drush.php';
21 * We set this context to let the shutdown function know we reached the end of drush_main().
25 function drush_postflight() {
26 drush_set_context("DRUSH_EXECUTION_COMPLETED", TRUE);
30 * Shutdown function for use while Drush and Drupal are bootstrapping and to return any
33 * The shutdown command checks whether certain options are set to reliably
34 * detect and log some common Drupal initialization errors.
36 * If the command is being executed with the --backend option, the script
37 * will return a json string containing the options and log information
40 * The command will exit with '1' if it was successfully executed, and the
41 * result of drush_get_error() if it wasn't.
43 function drush_shutdown() {
44 // Avoid doing anything if our container has not been initialized yet.
45 if (!Drush::hasContainer()) {
49 // Mysteriously make $user available during sess_write(). Avoids a NOTICE.
52 if (!drush_get_context('DRUSH_EXECUTION_COMPLETED', FALSE) && !drush_get_context('DRUSH_USER_ABORT', FALSE)) {
53 $php_error_message = '';
54 if ($error = error_get_last()) {
55 $php_error_message = "\n" . dt('Error: !message in !file, line !line', ['!message' => $error['message'], '!file' => $error['file'], '!line' => $error['line']]);
57 // We did not reach the end of the drush_main function,
58 // this generally means somewhere in the code a call to exit(),
59 // was made. We catch this, so that we can trigger an error in
61 drush_set_error("DRUSH_NOT_COMPLETED", dt("Drush command terminated abnormally due to an unrecoverable error.!message", ['!message' => $php_error_message]));
62 // Attempt to give the user some advice about how to fix the problem
66 if (Drush::backend()) {
67 drush_backend_output();
70 // This way drush_return_status() will always be the last shutdown function (unless other shutdown functions register shutdown functions...)
71 // and won't prevent other registered shutdown functions (IE from numerous cron methods) from running by calling exit() before they get a chance.
72 register_shutdown_function('drush_return_status');
76 * Shutdown function to save code coverage data.
78 function drush_coverage_shutdown() {
79 if ($file_name = drush_get_context('DRUSH_CODE_COVERAGE', FALSE)) {
80 $data = xdebug_get_code_coverage();
81 xdebug_stop_code_coverage();
83 // If coverage dump file contains anything, merge in the old data before
84 // saving. This happens if the current drush command invoked another drush
86 if (file_exists($file_name) && $content = file_get_contents($file_name)) {
87 $merge_data = unserialize($content);
88 if (is_array($merge_data)) {
89 foreach ($merge_data as $file => $lines) {
90 if (!isset($data[$file])) {
91 $data[$file] = $lines;
94 foreach ($lines as $num => $executed) {
95 if (!isset($data[$file][$num])) {
96 $data[$file][$num] = $executed;
99 $data[$file][$num] = ($executed == 1 ? $executed : $data[$file][$num]);
107 file_put_contents($file_name, serialize($data));
111 function drush_return_status() {
112 // If a specific exit code was set, then use it.
113 $exit_code = drush_get_context('DRUSH_EXIT_CODE');
114 if (empty($exit_code)) {
115 $exit_code = (drush_get_error()) ? DRUSH_FRAMEWORK_ERROR : DRUSH_SUCCESS;