-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
Runtime.php
157 lines (135 loc) · 5.08 KB
/
Runtime.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<?php
namespace Drush\Runtime;
use Drush\Drush;
use Drush\Preflight\Preflight;
use Drush\Runtime\ErrorHandler;
use Drush\Runtime\ShutdownHandler;
/**
* Control the Drush runtime environment
*
* - Preflight
* - Symfony application run
* - Bootstrap
* - Command execution
* - Termination
*/
class Runtime
{
/** @var Preflight */
protected $preflight;
/** @var DependencyInjection */
protected $di;
const DRUSH_RUNTIME_COMPLETED_NAMESPACE = 'runtime.execution.completed';
const DRUSH_RUNTIME_EXIT_CODE_NAMESPACE = 'runtime.exit_code';
/**
* Runtime constructor
*
* @param Preflight $preflight the preflight object
*/
public function __construct(Preflight $preflight, DependencyInjection $di)
{
$this->preflight = $preflight;
$this->di = $di;
}
/**
* Run the application, catching any errors that may be thrown.
* Typically, this will happen only for code that fails fast during
* preflight. Later code should catch and handle its own exceptions.
*/
public function run($argv)
{
try {
$output = new \Symfony\Component\Console\Output\ConsoleOutput();
$status = $this->doRun($argv, $output);
} catch (\Exception $e) {
$status = $e->getCode();
$message = $e->getMessage();
// Uncaught exceptions could happen early, before our logger
// and other classes are initialized. Print them and exit.
$this->preflight->logger()->setDebug(true)->log($message);
}
return $status;
}
/**
* Start up Drush
*/
protected function doRun($argv, $output)
{
// Do the preflight steps
$status = $this->preflight->preflight($argv);
// If preflight signals that we are done, then exit early.
if ($status !== false) {
return $status;
}
$commandfileSearchpath = $this->preflight->getCommandFilePaths();
$this->preflight->logger()->log('Commandfile search paths: ' . implode(',', $commandfileSearchpath));
$this->preflight->config()->set('runtime.commandfile.paths', $commandfileSearchpath);
// Require the Composer autoloader for Drupal (if different)
$loader = $this->preflight->loadSiteAutoloader();
// Create the Symfony Application et. al.
$input = $this->preflight->createInput();
$application = new \Drush\Application('Drush Commandline Tool', Drush::getVersion());
// Set up the DI container.
$container = $this->di->initContainer(
$application,
$this->preflight->config(),
$input,
$output,
$loader,
$this->preflight->drupalFinder(),
$this->preflight->aliasManager()
);
// Our termination handlers are set up via dependency injection,
// as they require classes that are set up in the DI container.
// We therefore cannot configure them any earlier than this.
$this->di->installHandlers($container);
// Now that the DI container has been set up, the Application object will
// have a reference to the bootstrap manager et. al., so we may use it
// as needed. Tell the application to coordinate between the Bootstrap
// manager and the alias manager to select a more specific URI, if
// one was not explicitly provided earlier in the preflight.
$application->refineUriSelection($this->preflight->environment()->cwd());
// Add global options and copy their values into Config.
$application->configureGlobalOptions();
// Configure the application object and register all of the commandfiles
// from the search paths we found above. After this point, the input
// and output objects are ready & we can start using the logger, etc.
$application->configureAndRegisterCommands($input, $output, $commandfileSearchpath);
// Run the Symfony Application
// Predispatch: call a remote Drush command if applicable (via a 'pre-init' hook)
// Bootstrap: bootstrap site to the level requested by the command (via a 'post-init' hook)
$status = $application->run($input, $output);
// Placate the Drush shutdown handler.
Runtime::setCompleted();
Runtime::setExitCode($status);
return $status;
}
/**
* Mark the current request as having completed successfully.
*/
public static function setCompleted()
{
Drush::config()->set(self::DRUSH_RUNTIME_COMPLETED_NAMESPACE, true);
}
/**
* @deprecated
* Used by backend.inc
*
* Mark the exit code for current request.
* @param int $code
*/
public static function setExitCode($code)
{
Drush::config()->set(self::DRUSH_RUNTIME_EXIT_CODE_NAMESPACE, $code);
}
/**
* @deprecated
* Used by backend.inc
*
* Get the exit code for current request.
*/
public static function exitCode()
{
return Drush::config()->get(self::DRUSH_RUNTIME_EXIT_CODE_NAMESPACE, DRUSH_SUCCESS);
}
}