first import
This commit is contained in:
@@ -0,0 +1 @@
|
||||
table.inc
|
||||
@@ -0,0 +1,656 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file Drush backend API
|
||||
*
|
||||
* When a drush command is called with the --backend option,
|
||||
* it will buffer all output, and instead return a JSON encoded
|
||||
* string containing all relevant information on the command that
|
||||
* was just executed.
|
||||
*
|
||||
* Through this mechanism, it is possible for Drush commands to
|
||||
* invoke each other.
|
||||
*
|
||||
* There are many cases where a command might wish to call another
|
||||
* command in its own process, to allow the calling command to
|
||||
* intercept and act on any errors that may occur in the script that
|
||||
* was called.
|
||||
*
|
||||
* A simple example is if there exists an 'update' command for running
|
||||
* update.php on a specific site. The original command might download
|
||||
* a newer version of a module for installation on a site, and then
|
||||
* run the update script in a separate process, so that in the case
|
||||
* of an error running a hook_update_n function, the module can revert
|
||||
* to a previously made database backup, and the previously installed code.
|
||||
*
|
||||
* By calling the script in a separate process, the calling script is insulated
|
||||
* from any error that occurs in the called script, to the level that if a
|
||||
* php code error occurs (ie: misformed file, missing parenthesis, whatever),
|
||||
* it is still able to reliably handle any problems that occur.
|
||||
*
|
||||
* This is nearly a RESTful API. @see http://en.wikipedia.org/wiki/REST
|
||||
*
|
||||
* Instead of :
|
||||
* http://[server]/[apipath]/[command]?[arg1]=[value1],[arg2]=[value2]
|
||||
*
|
||||
* It will call :
|
||||
* [apipath] [command] --[arg1]=[value1] --[arg2]=[value2] --backend
|
||||
*
|
||||
* [apipath] in this case will be the path to the drush.php file.
|
||||
* [command] is the command you would call, for instance 'status'.
|
||||
*
|
||||
* GET parameters will be passed as options to the script.
|
||||
* POST parameters will be passed to the script as a JSON encoded associative array over STDIN.
|
||||
*
|
||||
* Because of this standard interface, Drush commands can also be executed on
|
||||
* external servers through SSH pipes, simply by prepending, 'ssh username@server.com'
|
||||
* in front of the command.
|
||||
*
|
||||
* If the key-based ssh authentication has been set up between the servers,
|
||||
* this will just work. By default, drush is configured to disallow password
|
||||
* authentication; if you would like to enter a password for every connection,
|
||||
* then in your drushrc.php file, set $options['ssh-options'] so that it does NOT
|
||||
* include '-o PasswordAuthentication=no'. See examples/example.drushrc.php.
|
||||
*
|
||||
* The results from backend API calls can be fetched via a call to
|
||||
* drush_backend_get_result().
|
||||
*/
|
||||
|
||||
/**
|
||||
* Identify the JSON encoded output from a command.
|
||||
*/
|
||||
define('DRUSH_BACKEND_OUTPUT_DELIMITER', 'DRUSH_BACKEND_OUTPUT_START>>>%s<<<DRUSH_BACKEND_OUTPUT_END');
|
||||
|
||||
function drush_backend_set_result($value) {
|
||||
if (drush_get_context('DRUSH_BACKEND')) {
|
||||
drush_set_context('BACKEND_RESULT', $value);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Retrieves the results from the last call to backend_invoke.
|
||||
*
|
||||
* @returns array
|
||||
* An associative array containing information from the last
|
||||
* backend invoke. The keys in the array include:
|
||||
*
|
||||
* - output: This item contains the textual output of
|
||||
* the command that was executed.
|
||||
* - object: Contains the PHP object representation of the
|
||||
* result of the command.
|
||||
* - self: The self object contains the alias record that was
|
||||
* used to select the bootstrapped site when the command was
|
||||
* executed.
|
||||
* - error_status: This item returns the error status for the
|
||||
* command. Zero means "no error".
|
||||
* - log: The log item contains an array of log messages from
|
||||
* the command execution ordered chronologically. Each log
|
||||
* entery is an associative array. A log entry contains
|
||||
* following items:
|
||||
* o type: The type of log entry, such as 'notice' or 'warning'
|
||||
* o message: The log message
|
||||
* o timestamp: The time that the message was logged
|
||||
* o memory: Available memory at the time that the message was logged
|
||||
* o error: The error code associated with the log message
|
||||
* (only for log entries whose type is 'error')
|
||||
* - error_log: The error_log item contains another representation
|
||||
* of entries from the log. Only log entries whose 'error' item
|
||||
* is set will appear in the error log. The error log is an
|
||||
* associative array whose key is the error code, and whose value
|
||||
* is an array of messages--one message for every log entry with
|
||||
* the same error code.
|
||||
* - context: The context item contains a representation of all option
|
||||
* values that affected the operation of the command, including both
|
||||
* the command line options, options set in a drushrc.php configuration
|
||||
* files, and options set from the alias record used with the command.
|
||||
*/
|
||||
function drush_backend_get_result() {
|
||||
return drush_get_context('BACKEND_RESULT');
|
||||
}
|
||||
|
||||
function drush_backend_output() {
|
||||
$data = array();
|
||||
|
||||
$data['output'] = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
$result_object = drush_backend_get_result();
|
||||
if (isset($result_object)) {
|
||||
$data['object'] = $result_object;
|
||||
}
|
||||
|
||||
$error = drush_get_error();
|
||||
$data['error_status'] = ($error) ? $error : DRUSH_SUCCESS;
|
||||
|
||||
$data['log'] = drush_get_log(); // Append logging information
|
||||
// The error log is a more specific version of the log, and may be used by calling
|
||||
// scripts to check for specific errors that have occurred.
|
||||
$data['error_log'] = drush_get_error_log();
|
||||
// If there is a @self record, then include it in the result
|
||||
$self_record = drush_sitealias_get_record('@self');
|
||||
if (!empty($self_record)) {
|
||||
$site_context = drush_get_context('site', array());
|
||||
unset($site_context['config-file']);
|
||||
unset($site_context['context-path']);
|
||||
unset($self_record['loaded-config']);
|
||||
unset($self_record['#name']);
|
||||
$data['self'] = array_merge($site_context, $self_record);
|
||||
}
|
||||
|
||||
// Return the options that were set at the end of the process.
|
||||
$data['context'] = drush_get_merged_options();
|
||||
if (!drush_get_context('DRUSH_QUIET')) {
|
||||
printf(DRUSH_BACKEND_OUTPUT_DELIMITER, json_encode($data));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse output returned from a Drush command.
|
||||
*
|
||||
* @param string
|
||||
* The output of a drush command
|
||||
* @param integrate
|
||||
* Integrate the errors and log messages from the command into the current process.
|
||||
*
|
||||
* @return
|
||||
* An associative array containing the data from the external command, or the string parameter if it
|
||||
* could not be parsed successfully.
|
||||
*/
|
||||
function drush_backend_parse_output($string, $integrate = TRUE) {
|
||||
$regex = sprintf(DRUSH_BACKEND_OUTPUT_DELIMITER, '(.*)');
|
||||
|
||||
preg_match("/$regex/s", $string, $match);
|
||||
|
||||
if ($match[1]) {
|
||||
// we have our JSON encoded string
|
||||
$output = $match[1];
|
||||
// remove the match we just made and any non printing characters
|
||||
$string = trim(str_replace(sprintf(DRUSH_BACKEND_OUTPUT_DELIMITER, $match[1]), '', $string));
|
||||
}
|
||||
|
||||
if ($output) {
|
||||
$data = json_decode($output, TRUE);
|
||||
if (is_array($data)) {
|
||||
if ($integrate) {
|
||||
_drush_backend_integrate($data);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Integrate log messages and error statuses into the current process.
|
||||
*
|
||||
* Output produced by the called script will be printed, errors will be set
|
||||
* and log messages will be logged locally.
|
||||
*
|
||||
* @param data
|
||||
* The associative array returned from the external command.
|
||||
*/
|
||||
function _drush_backend_integrate($data) {
|
||||
if (is_array($data['log'])) {
|
||||
foreach($data['log'] as $log) {
|
||||
$message = is_array($log['message']) ? implode("\n", $log['message']) : $log['message'];
|
||||
if (!is_null($log['error'])) {
|
||||
drush_set_error($log['error'], $message);
|
||||
}
|
||||
else {
|
||||
drush_log($message, $log['type']);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Output will either be printed, or buffered to the drush_backend_output command.
|
||||
if (drush_cmp_error('DRUSH_APPLICATION_ERROR') && !empty($data['output'])) {
|
||||
drush_set_error("DRUSH_APPLICATION_ERROR", dt("Output from failed command :\n !output", array('!output' => $data['output'])));
|
||||
}
|
||||
else {
|
||||
print ($data['output']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Call an external command using proc_open.
|
||||
*
|
||||
* @param cmd
|
||||
* The command to execute. This command already needs to be properly escaped.
|
||||
* @param data
|
||||
* An associative array that will be JSON encoded and passed to the script being called.
|
||||
* Objects are not allowed, as they do not json_decode gracefully.
|
||||
*
|
||||
* @return
|
||||
* False if the command could not be executed, or did not return any output.
|
||||
* If it executed successfully, it returns an associative array containing the command
|
||||
* called, the output of the command, and the error code of the command.
|
||||
*/
|
||||
function _drush_proc_open($cmd, $data = NULL, $context = NULL) {
|
||||
$descriptorspec = array(
|
||||
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
|
||||
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
|
||||
2 => array("pipe", "w") // stderr is a pipe the child will write to
|
||||
);
|
||||
if (drush_get_context('DRUSH_SIMULATE')) {
|
||||
drush_print('proc_open: ' . $cmd);
|
||||
return FALSE;
|
||||
}
|
||||
$process = proc_open($cmd, $descriptorspec, $pipes, null, null, array('context' => $context));
|
||||
if (is_resource($process)) {
|
||||
if ($data) {
|
||||
fwrite($pipes[0], json_encode($data)); // pass the data array in a JSON encoded string
|
||||
}
|
||||
|
||||
$info = stream_get_meta_data($pipes[1]);
|
||||
stream_set_blocking($pipes[1], TRUE);
|
||||
stream_set_timeout($pipes[1], 1);
|
||||
$string = '';
|
||||
while (!feof($pipes[1]) && !$info['timed_out']) {
|
||||
$string .= fgets($pipes[1], 4096);
|
||||
$info = stream_get_meta_data($pipes[1]);
|
||||
flush();
|
||||
};
|
||||
|
||||
$info = stream_get_meta_data($pipes[2]);
|
||||
stream_set_blocking($pipes[2], TRUE);
|
||||
stream_set_timeout($pipes[2], 1);
|
||||
while (!feof($pipes[2]) && !$info['timed_out']) {
|
||||
$string .= fgets($pipes[2], 4096);
|
||||
$info = stream_get_meta_data($pipes[2]);
|
||||
flush();
|
||||
};
|
||||
|
||||
fclose($pipes[0]);
|
||||
fclose($pipes[1]);
|
||||
fclose($pipes[2]);
|
||||
$code = proc_close($process);
|
||||
return array('cmd' => $cmd, 'output' => $string, 'code' => $code);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke a drush backend command.
|
||||
*
|
||||
* @param command
|
||||
* A defined drush command such as 'cron', 'status' or any of the available ones such as 'drush pm'.
|
||||
* @param data
|
||||
* Optional. An array containing options to pass to the call. Common options would be 'uri' if you want to call a command
|
||||
* on a different site, or 'root', if you want to call a command using a different Drupal installation.
|
||||
* Array items with a numeric key are treated as optional arguments to the command.
|
||||
* @param method
|
||||
* Optional. Defaults to 'GET'.
|
||||
* If this parameter is set to 'POST', the $data array will be passed to the script being called as a JSON encoded string over
|
||||
* the STDIN pipe of that process. This is preferable if you have to pass sensitive data such as passwords and the like.
|
||||
* For any other value, the $data array will be collapsed down into a set of command line options to the script.
|
||||
* @param integrate
|
||||
* Optional. Defaults to TRUE.
|
||||
* If TRUE, any error statuses or log messages will be integrated into the current process. This might not be what you want,
|
||||
* if you are writing a command that operates on multiple sites.
|
||||
* @param drush_path
|
||||
* Optional. Defaults to the current drush.php file on the local machine, and
|
||||
* to simply 'drush' (the drush script in the current PATH) on remote servers.
|
||||
* You may also specify a different drush.php script explicitly. You will need
|
||||
* to set this when calling drush on a remote server if 'drush' is not in the
|
||||
* PATH on that machine.
|
||||
* @param hostname
|
||||
* Optional. A remote host to execute the drush command on.
|
||||
* @param username
|
||||
* Optional. Defaults to the current user. If you specify this, you can choose which module to send.
|
||||
*
|
||||
* @deprecated Command name includes arguments, and these are not quote-escaped in any way.
|
||||
* @see drush_invoke_process("@self", $command, array($arg1, $arg2, ...), $data) for a better option.
|
||||
*
|
||||
* @return
|
||||
* If the command could not be completed successfully, FALSE.
|
||||
* If the command was completed, this will return an associative array containing the data from drush_backend_output().
|
||||
*/
|
||||
function drush_backend_invoke($command, $data = array(), $method = 'GET', $integrate = TRUE, $drush_path = NULL, $hostname = NULL, $username = NULL) {
|
||||
$args = explode(" ", $command);
|
||||
$command = array_shift($args);
|
||||
return drush_backend_invoke_args($command, $args, $data, $method, $integrate, $drush_path, $hostname, $username);
|
||||
}
|
||||
|
||||
/**
|
||||
* A variant of drush_backend_invoke() which specifies command and arguments separately.
|
||||
*
|
||||
* @deprecated; do not call directly.
|
||||
* @see drush_invoke_process("@self", $command, $args, $data) for a better option.
|
||||
*/
|
||||
function drush_backend_invoke_args($command, $args, $data = array(), $method = 'GET', $integrate = TRUE, $drush_path = NULL, $hostname = NULL, $username = NULL, $ssh_options = NULL) {
|
||||
$cmd = _drush_backend_generate_command($command, $args, $data, $method, $drush_path, $hostname, $username, $ssh_options);
|
||||
return _drush_backend_invoke($cmd, $data, array_key_exists('#integrate', $data) ? $data['#integrate'] : $integrate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a new local or remote command in a new process.
|
||||
*
|
||||
* @param site_record
|
||||
* An array containing information used to generate the command.
|
||||
* 'remote-host'
|
||||
* Optional. A remote host to execute the drush command on.
|
||||
* 'remote-user'
|
||||
* Optional. Defaults to the current user. If you specify this, you can choose which module to send.
|
||||
* 'ssh-options'
|
||||
* Optional. Defaults to "-o PasswordAuthentication=no"
|
||||
* 'path-aliases'
|
||||
* Optional; contains paths to folders and executables useful to the command.
|
||||
* '%drush-script'
|
||||
* Optional. Defaults to the current drush.php file on the local machine, and
|
||||
* to simply 'drush' (the drush script in the current PATH) on remote servers.
|
||||
* You may also specify a different drush.php script explicitly. You will need
|
||||
* to set this when calling drush on a remote server if 'drush' is not in the
|
||||
* PATH on that machine.
|
||||
* @param command
|
||||
* A defined drush command such as 'cron', 'status' or any of the available ones such as 'drush pm'.
|
||||
* @param args
|
||||
* An array of arguments for the command.
|
||||
* @param data
|
||||
* Optional. An array containing options to pass to the remote script.
|
||||
* Array items with a numeric key are treated as optional arguments to the command.
|
||||
* This parameter is a reference, as any options that have been represented as either an option, or an argument will be removed.
|
||||
* This allows you to pass the left over options as a JSON encoded string, without duplicating data.
|
||||
* @param method
|
||||
* Optional. Defaults to 'GET'.
|
||||
* If this parameter is set to 'POST', the $data array will be passed to the script being called as a JSON encoded string over
|
||||
* the STDIN pipe of that process. This is preferable if you have to pass sensitive data such as passwords and the like.
|
||||
* For any other value, the $data array will be collapsed down into a set of command line options to the script.
|
||||
* @param integrate
|
||||
* Optional. Defaults to TRUE.
|
||||
* If TRUE, any error statuses or log messages will be integrated into the current process. This might not be what you want,
|
||||
* if you are writing a command that operates on multiple sites.
|
||||
*
|
||||
* @return
|
||||
* A text string representing a fully escaped command.
|
||||
*
|
||||
* @deprecated; do not call directly.
|
||||
* @see drush_invoke_process($site_record, $command, $args, $data) for a better option.
|
||||
*/
|
||||
function drush_backend_invoke_sitealias($site_record, $command, $args, $data = array(), $method = 'GET', $integrate = TRUE) {
|
||||
$cmd = _drush_backend_generate_command_sitealias($site_record, $command, $args, $data, $method);
|
||||
return _drush_backend_invoke($cmd, $data, array_key_exists('#integrate', $data) ? $data['#integrate'] : $integrate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new pipe with proc_open, and attempt to parse the output.
|
||||
*
|
||||
* We use proc_open instead of exec or others because proc_open is best
|
||||
* for doing bi-directional pipes, and we need to pass data over STDIN
|
||||
* to the remote script.
|
||||
*
|
||||
* Exec also seems to exhibit some strangeness in keeping the returned
|
||||
* data intact, in that it modifies the newline characters.
|
||||
*
|
||||
* @param cmd
|
||||
* The complete command line call to use.
|
||||
* @param data
|
||||
* An associative array to pass to the remote script.
|
||||
* @param integrate
|
||||
* Integrate data from remote script with local process.
|
||||
*
|
||||
* @return
|
||||
* If the command could not be completed successfully, FALSE.
|
||||
* If the command was completed, this will return an associative array containing the data from drush_backend_output().
|
||||
*/
|
||||
function _drush_backend_invoke($cmd, $data = null, $integrate = TRUE) {
|
||||
drush_log(dt('Running: !cmd', array('!cmd' => $cmd)), 'command');
|
||||
if (array_key_exists('#interactive', $data)) {
|
||||
drush_log(dt("executing !cmd", array('!cmd' => $cmd)));
|
||||
return drush_op_system($cmd);
|
||||
}
|
||||
else {
|
||||
$proc = _drush_proc_open($cmd, $data);
|
||||
|
||||
if (($proc['code'] == DRUSH_APPLICATION_ERROR) && $integrate) {
|
||||
drush_set_error('DRUSH_APPLICATION_ERROR', dt("The external command could not be executed due to an application error."));
|
||||
}
|
||||
|
||||
if ($proc['output']) {
|
||||
$values = drush_backend_parse_output($proc['output'], $integrate);
|
||||
if (is_array($values)) {
|
||||
return $values;
|
||||
}
|
||||
else {
|
||||
return drush_set_error('DRUSH_FRAMEWORK_ERROR', dt("The command could not be executed successfully (returned: !return, code: %code)", array("!return" => $proc['output'], "%code" => $proc['code'])));
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a command to execute.
|
||||
*
|
||||
* @param command
|
||||
* A defined drush command such as 'cron', 'status' or any of the available ones such as 'drush pm'.
|
||||
* @param args
|
||||
* An array of arguments for the command.
|
||||
* @param data
|
||||
* Optional. An array containing options to pass to the remote script.
|
||||
* Array items with a numeric key are treated as optional arguments to the command.
|
||||
* This parameter is a reference, as any options that have been represented as either an option, or an argument will be removed.
|
||||
* This allows you to pass the left over options as a JSON encoded string, without duplicating data.
|
||||
* @param method
|
||||
* Optional. Defaults to 'GET'.
|
||||
* If this parameter is set to 'POST', the $data array will be passed to the script being called as a JSON encoded string over
|
||||
* the STDIN pipe of that process. This is preferable if you have to pass sensitive data such as passwords and the like.
|
||||
* For any other value, the $data array will be collapsed down into a set of command line options to the script.
|
||||
* @param drush_path
|
||||
* Optional. Defaults to the current drush.php file on the local machine, and
|
||||
* to simply 'drush' (the drush script in the current PATH) on remote servers.
|
||||
* You may also specify a different drush.php script explicitly. You will need
|
||||
* to set this when calling drush on a remote server if 'drush' is not in the
|
||||
* PATH on that machine.
|
||||
* @param hostname
|
||||
* Optional. A remote host to execute the drush command on.
|
||||
* @param username
|
||||
* Optional. Defaults to the current user. If you specify this, you can choose which module to send.
|
||||
*
|
||||
* @return
|
||||
* A text string representing a fully escaped command.
|
||||
*
|
||||
* @deprecated Is not as flexible as recommended command. @see _drush_backend_generate_command_sitealias().
|
||||
*/
|
||||
function _drush_backend_generate_command($command, $args, &$data, $method = 'GET', $drush_path = null, $hostname = null, $username = null, $ssh_options = NULL) {
|
||||
return _drush_backend_generate_command_sitealias(
|
||||
array(
|
||||
'remote-host' => $hostname,
|
||||
'remote-user' => $username,
|
||||
'ssh-options' => $ssh_options,
|
||||
'path-aliases' => array(
|
||||
'%drush-script' => $drush_path,
|
||||
),
|
||||
), $command, $args, $data, $method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a command to execute.
|
||||
*
|
||||
* @param site_record
|
||||
* An array containing information used to generate the command.
|
||||
* 'remote-host'
|
||||
* Optional. A remote host to execute the drush command on.
|
||||
* 'remote-user'
|
||||
* Optional. Defaults to the current user. If you specify this, you can choose which module to send.
|
||||
* 'ssh-options'
|
||||
* Optional. Defaults to "-o PasswordAuthentication=no"
|
||||
* 'path-aliases'
|
||||
* Optional; contains paths to folders and executables useful to the command.
|
||||
* '%drush-script'
|
||||
* Optional. Defaults to the current drush.php file on the local machine, and
|
||||
* to simply 'drush' (the drush script in the current PATH) on remote servers.
|
||||
* You may also specify a different drush.php script explicitly. You will need
|
||||
* to set this when calling drush on a remote server if 'drush' is not in the
|
||||
* PATH on that machine.
|
||||
* @param command
|
||||
* A defined drush command such as 'cron', 'status' or any of the available ones such as 'drush pm'.
|
||||
* @param args
|
||||
* An array of arguments for the command.
|
||||
* @param data
|
||||
* Optional. An array containing options to pass to the remote script.
|
||||
* Array items with a numeric key are treated as optional arguments to the command.
|
||||
* This parameter is a reference, as any options that have been represented as either an option, or an argument will be removed.
|
||||
* This allows you to pass the left over options as a JSON encoded string, without duplicating data.
|
||||
* @param method
|
||||
* Optional. Defaults to 'GET'.
|
||||
* If this parameter is set to 'POST', the $data array will be passed to the script being called as a JSON encoded string over
|
||||
* the STDIN pipe of that process. This is preferable if you have to pass sensitive data such as passwords and the like.
|
||||
* For any other value, the $data array will be collapsed down into a set of command line options to the script.
|
||||
*
|
||||
* @return
|
||||
* A text string representing a fully escaped command.
|
||||
*/
|
||||
function _drush_backend_generate_command_sitealias($site_record, $command, $args, &$data, $method = 'GET') {
|
||||
$drush_path = null;
|
||||
|
||||
$hostname = array_key_exists('remote-host', $site_record) ? $site_record['remote-host'] : null;
|
||||
$username = array_key_exists('remote-user', $site_record) ? $site_record['remote-user'] : null;
|
||||
$ssh_options = array_key_exists('ssh-options', $site_record) ? $site_record['ssh-options'] : null;
|
||||
$os = drush_os($site_record);
|
||||
|
||||
$drush_path = NULL;
|
||||
if (array_key_exists('path-aliases', $site_record)) {
|
||||
if (array_key_exists('%drush-script', $site_record['path-aliases'])) {
|
||||
$drush_path = $site_record['path-aliases']['%drush-script'];
|
||||
}
|
||||
}
|
||||
|
||||
if (drush_is_local_host($hostname)) {
|
||||
$hostname = null;
|
||||
}
|
||||
|
||||
$drush_path = !is_null($drush_path) ? $drush_path : (is_null($hostname) ? DRUSH_COMMAND : 'drush'); // Call own drush.php file on local machines, or 'drush' on remote machines.
|
||||
$data['root'] = array_key_exists('root', $data) ? $data['root'] : drush_get_context('DRUSH_DRUPAL_ROOT');
|
||||
$data['uri'] = array_key_exists('uri', $data) ? $data['uri'] : drush_get_context('DRUSH_URI');
|
||||
|
||||
$option_str = _drush_backend_argument_string($data, $method);
|
||||
foreach ($data as $key => $arg) {
|
||||
if (is_numeric($key)) {
|
||||
$args[] = $arg;
|
||||
unset($data[$key]);
|
||||
}
|
||||
}
|
||||
foreach ($args as $arg) {
|
||||
$command .= ' ' . drush_escapeshellarg($arg);
|
||||
}
|
||||
$interactive = ' ' . (empty($data['#interactive']) ? '' : ' > `tty`') . ' 2>&1';
|
||||
// @TODO: Implement proper multi platform / multi server support.
|
||||
$cmd = escapeshellcmd($drush_path) . " " . $option_str . " " . $command . (empty($data['#interactive']) ? " --backend" : "");
|
||||
|
||||
if (!is_null($hostname)) {
|
||||
$username = (!is_null($username)) ? drush_escapeshellarg($username) . "@" : '';
|
||||
$ssh_options = (!is_null($ssh_options)) ? $ssh_options : drush_get_option('ssh-options', "-o PasswordAuthentication=no");
|
||||
$cmd = "ssh " . $ssh_options . " " . $username . drush_escapeshellarg($hostname) . " " . drush_escapeshellarg($cmd . ' 2>&1', $os) . $interactive;
|
||||
}
|
||||
else {
|
||||
$cmd .= $interactive;
|
||||
}
|
||||
|
||||
return $cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
* A small utility function to call a drush command in the background.
|
||||
*
|
||||
* Takes the same parameters as drush_backend_invoke, but forks a new
|
||||
* process by calling the command using system() and adding a '&' at the
|
||||
* end of the command.
|
||||
*
|
||||
* Use this if you don't care what the return value of the command may be.
|
||||
*/
|
||||
function drush_backend_fork($command, $data, $drush_path = null, $hostname = null, $username = null) {
|
||||
$data['quiet'] = TRUE;
|
||||
$args = explode(" ", $command);
|
||||
$command = array_shift($args);
|
||||
$cmd = "(" . _drush_backend_generate_command($command, $args, $data, 'GET', $drush_path, $hostname, $username) . ' &) > /dev/null';
|
||||
drush_op_system($cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map the options to a string containing all the possible arguments and options.
|
||||
*
|
||||
* @param data
|
||||
* Optional. An array containing options to pass to the remote script.
|
||||
* Array items with a numeric key are treated as optional arguments to the command.
|
||||
* This parameter is a reference, as any options that have been represented as either an option, or an argument will be removed.
|
||||
* This allows you to pass the left over options as a JSON encoded string, without duplicating data.
|
||||
* @param method
|
||||
* Optional. Defaults to 'GET'.
|
||||
* If this parameter is set to 'POST', the $data array will be passed to the script being called as a JSON encoded string over
|
||||
* the STDIN pipe of that process. This is preferable if you have to pass sensitive data such as passwords and the like.
|
||||
* For any other value, the $data array will be collapsed down into a set of command line options to the script.
|
||||
* @return
|
||||
* A properly formatted and escaped set of arguments and options to append to the drush.php shell command.
|
||||
*/
|
||||
function _drush_backend_argument_string(&$data, $method = 'GET') {
|
||||
// Named keys are options, numerically indexed keys are optional arguments.
|
||||
$args = array();
|
||||
$options = array();
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
if (!is_array($value) && !is_object($value) && !is_null($value) && ($value != '')) {
|
||||
if (is_numeric($key)) {
|
||||
$args[$key] = $value;
|
||||
}
|
||||
elseif (substr($key,0,1) != '#') {
|
||||
$options[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (array_key_exists('backend', $data)) {
|
||||
unset($data['backend']);
|
||||
}
|
||||
|
||||
$special = array('root', 'uri'); // These should be in the command line.
|
||||
$option_str = '';
|
||||
foreach ($options as $key => $value) {
|
||||
if (($method != 'POST') || (($method == 'POST') && in_array($key, $special))) {
|
||||
$option_str .= _drush_escape_option($key, $value);
|
||||
unset($data[$key]); // Remove items in the data array.
|
||||
}
|
||||
}
|
||||
|
||||
return $option_str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a properly formatted and escaped command line option
|
||||
*
|
||||
* @param key
|
||||
* The name of the option.
|
||||
* @param value
|
||||
* The value of the option.
|
||||
*
|
||||
* @return
|
||||
* If the value is set to TRUE, this function will return " --key"
|
||||
* In other cases it will return " --key='value'"
|
||||
*/
|
||||
function _drush_escape_option($key, $value = TRUE) {
|
||||
if ($value !== TRUE) {
|
||||
$option_str = " --$key=" . escapeshellarg($value);
|
||||
}
|
||||
else {
|
||||
$option_str = " --$key";
|
||||
}
|
||||
return $option_str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read options fron STDIN during POST requests.
|
||||
*
|
||||
* This function will read any text from the STDIN pipe,
|
||||
* and attempts to generate an associative array if valid
|
||||
* JSON was received.
|
||||
*
|
||||
* @return
|
||||
* An associative array of options, if successfull. Otherwise FALSE.
|
||||
*/
|
||||
function _drush_backend_get_stdin() {
|
||||
$fp = fopen('php://stdin', 'r');
|
||||
stream_set_blocking($fp, FALSE);
|
||||
$string = stream_get_contents($fp);
|
||||
fclose($fp);
|
||||
if (trim($string)) {
|
||||
return json_decode($string, TRUE);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Drush batch API.
|
||||
*
|
||||
* This file contains a fork of the Drupal Batch API that has been drastically
|
||||
* simplified and tailored to Drush's unique use case.
|
||||
*
|
||||
* The existing API is very targeted towards environments that are web accessible,
|
||||
* and would frequently attempt to redirect the user which would result in the
|
||||
* drush process being completely destroyed with no hope of recovery.
|
||||
*
|
||||
* While the original API does offer a 'non progressive' mode which simply
|
||||
* calls each operation in sequence within the current process, in most
|
||||
* implementations (Drupal 5 and 6), it would still attempt to redirect
|
||||
* unless very specific conditions were met.
|
||||
*
|
||||
* When operating in 'non progressive' mode, Drush would experience the problems
|
||||
* that the API was written to solve in the first place, specifically that processes
|
||||
* would exceed the available memory and exit with an error.
|
||||
*
|
||||
* Each major release of Drupal has also had slightly different implementations
|
||||
* of the batch API, and this provides a uniform interface to all of these
|
||||
* implementations.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Process a Drupal batch by spawning multiple Drush processes.
|
||||
*
|
||||
* This function will include the correct batch engine for the current
|
||||
* major version of Drupal, and will make use of the drush_backend_invoke
|
||||
* system to spawn multiple worker threads to handle the processing of
|
||||
* the current batch, while keeping track of available memory.
|
||||
*
|
||||
* The batch system will process as many batch sets as possible until
|
||||
* the entire batch has been completed or half of the available memory
|
||||
* has been used.
|
||||
*
|
||||
* This function is a drop in replacement for the existing batch_process()
|
||||
* function of Drupal.
|
||||
*
|
||||
* @param command
|
||||
* The command to call for the back end process. By default this will be
|
||||
* the 'backend-process' command, but some commands such as updatedb will
|
||||
* have special initialization requirements, and will need to define and
|
||||
* use their own command.
|
||||
*
|
||||
*/
|
||||
function drush_backend_batch_process($command = 'batch-process') {
|
||||
drush_include_engine('drupal', 'batch', drush_drupal_major_version());
|
||||
_drush_backend_batch_process($command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process sets from the specified batch.
|
||||
*
|
||||
* This function is called by the worker process that is spawned by the
|
||||
* drush_backend_batch_process function.
|
||||
*
|
||||
* The command called needs to call this function after it's special bootstrap
|
||||
* requirements have been taken care of.
|
||||
*/
|
||||
function drush_batch_command($id) {
|
||||
include_once('includes/batch.inc');
|
||||
drush_include_engine('drupal', 'batch', drush_drupal_major_version());
|
||||
_drush_batch_command($id);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,597 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* The Drush context API implementation.
|
||||
*
|
||||
* This API acts as a storage mechanism for all options, arguments and
|
||||
* configuration settings that are loaded into drush.
|
||||
*
|
||||
* This API also acts as an IPC mechanism between the different drush commands,
|
||||
* and provides protection from accidentally overriding settings that are
|
||||
* needed by other parts of the system.
|
||||
*
|
||||
* It also avoids the necessity to pass references through the command chain
|
||||
* and allows the scripts to keep track of whether any settings have changed
|
||||
* since the previous execution.
|
||||
*
|
||||
* This API defines several contexts that are used by default.
|
||||
*
|
||||
* Argument contexts :
|
||||
* These contexts are used by Drush to store information on the command.
|
||||
* They have their own access functions in the forms of
|
||||
* drush_set_arguments(), drush_get_arguments(), drush_set_command(),
|
||||
* drush_get_command().
|
||||
*
|
||||
* command : The drush command being executed.
|
||||
* arguments : Any additional arguments that were specified.
|
||||
*
|
||||
* Setting contexts :
|
||||
* These contexts store options that have been passed to the drush.php
|
||||
* script, either through the use of any of the config files, directly from
|
||||
* the command line through --option='value' or through a JSON encoded string
|
||||
* passed through the STDIN pipe.
|
||||
*
|
||||
* These contexts are accessible through the drush_get_option() and
|
||||
* drush_set_option() functions. See drush_context_names() for a description
|
||||
* of all of the contexts.
|
||||
*
|
||||
* Drush commands may also choose to save settings for a specific context to
|
||||
* the matching configuration file through the drush_save_config() function.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Return a list of the valid drush context names.
|
||||
*
|
||||
* These context names are carefully ordered from
|
||||
* highest to lowest priority.
|
||||
*
|
||||
* These contexts are evaluated in a certain order, and the highest priority value
|
||||
* is returned by default from drush_get_option. This allows scripts to check whether
|
||||
* an option was different before the current execution.
|
||||
*
|
||||
* Specified by the script itself :
|
||||
* process : Generated in the current process.
|
||||
* cli : Passed as --option=value to the command line.
|
||||
* stdin : Passed as a JSON encoded string through stdin.
|
||||
* specific : Defined in a command-specific option record, and
|
||||
* set in the command context whenever that command is used.
|
||||
* alias : Defined in an alias record, and set in the
|
||||
* alias context whenever that alias is used.
|
||||
*
|
||||
* Specified by config files :
|
||||
* custom : Loaded from the config file specified by --config or -c
|
||||
* site : Loaded from the drushrc.php file in the Drupal site directory.
|
||||
* drupal : Loaded from the drushrc.php file in the Drupal root directory.
|
||||
* user : Loaded from the drushrc.php file in the user's home directory.
|
||||
* home.drush Loaded from the drushrc.php file in the $HOME/.drush directory.
|
||||
* system : Loaded from the drushrc.php file in the system's $PREFIX/etc/drush directory.
|
||||
* drush : Loaded from the drushrc.php file in the same directory as drush.php.
|
||||
*
|
||||
* Specified by the script, but has the lowest priority :
|
||||
* default : The script might provide some sensible defaults during init.
|
||||
*/
|
||||
function drush_context_names() {
|
||||
static $contexts = array(
|
||||
'process', 'cli', 'stdin', 'specific', 'alias',
|
||||
'custom', 'site', 'drupal', 'user', 'home.drush', 'system',
|
||||
'drush', 'default');
|
||||
|
||||
return $contexts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of possible drushrc file locations.
|
||||
*
|
||||
* @context
|
||||
* A valid drush context from drush_context_names().
|
||||
* @prefix
|
||||
* Optional. Specify a prefix to prepend to ".drushrc.php" when looking
|
||||
* for config files. Most likely used by contrib commands.
|
||||
* @return
|
||||
* An associative array containing possible config files to load
|
||||
* The keys are the 'context' of the files, the values are the file
|
||||
* system locations.
|
||||
*/
|
||||
function _drush_config_file($context, $prefix = NULL) {
|
||||
$configs = array();
|
||||
$config_file = $prefix ? $prefix . '.' . 'drushrc.php' : 'drushrc.php';
|
||||
|
||||
// Did the user explicitly specify a config file?
|
||||
if ($config = drush_get_option(array('c', 'config'))) {
|
||||
if (is_dir($config)) {
|
||||
$config = $config . '/drushrc.php';
|
||||
}
|
||||
$configs['custom'] = $config;
|
||||
}
|
||||
|
||||
if ($site_path = drush_get_context('DRUSH_DRUPAL_SITE_ROOT')) {
|
||||
$configs['site'] = $site_path . "/" . $config_file;
|
||||
}
|
||||
|
||||
if ($drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT')) {
|
||||
$configs['drupal'] = $drupal_root . '/' . $config_file;
|
||||
}
|
||||
|
||||
// in the user home directory
|
||||
if (!is_null(drush_server_home())) {
|
||||
$configs['user'] = drush_server_home() . '/.' . $config_file;
|
||||
}
|
||||
|
||||
// in $HOME/.drush directory
|
||||
if (!is_null(drush_server_home())) {
|
||||
$configs['home.drush'] = drush_server_home() . '/.drush/' . $config_file;
|
||||
}
|
||||
|
||||
// In the system wide configuration folder.
|
||||
$configs['system'] = drush_get_context('ETC_PREFIX', '') . '/etc/drush/' . $config_file;
|
||||
|
||||
// in the drush installation folder
|
||||
$configs['drush'] = dirname(__FILE__) . '/../' . $config_file;
|
||||
|
||||
return empty($configs[$context]) ? '' : $configs[$context];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load drushrc files (if available) from several possible locations.
|
||||
*/
|
||||
function drush_load_config($context) {
|
||||
drush_load_config_file($context, _drush_config_file($context));
|
||||
}
|
||||
|
||||
function drush_load_config_file($context, $config) {
|
||||
if (file_exists($config)) {
|
||||
$options = $aliases = $command_specific = $override = array();
|
||||
drush_log(dt('Loading drushrc "!config" into "!context" scope.', array('!config' => realpath($config), '!context' => $context)), 'bootstrap');
|
||||
$ret = @include_once($config);
|
||||
if ($ret === FALSE) {
|
||||
drush_log(dt('Cannot open drushrc "!config", ignoring.', array('!config' => realpath($config))), 'warning');
|
||||
return FALSE;
|
||||
}
|
||||
if (!empty($options) || !empty($aliases) || !empty($command_specific)) {
|
||||
$options = array_merge(drush_get_context($context), $options);
|
||||
$options['config-file'] = realpath($config);
|
||||
|
||||
//$options['site-aliases'] = array_merge(isset($aliases) ? $aliases : array(), isset($options['site-aliases']) ? $options['site-aliases'] : array());
|
||||
unset($options['site-aliases']);
|
||||
$options['command-specific'] = array_merge(isset($command_specific) ? $command_specific : array(), isset($options['command-specific']) ? $options['command-specific'] : array());
|
||||
|
||||
drush_set_config_options($context, $options, $override);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function drush_set_config_options($context, $options, $override = array()) {
|
||||
global $drush_conf_override;
|
||||
|
||||
// Only reset $drush_conf_override if the array is not set, otherwise keep old values and append new values to it.
|
||||
if (!isset($drush_conf_override)) {
|
||||
$drush_conf_override = array();
|
||||
}
|
||||
|
||||
// Copy 'config-file' into 'context-path', converting to an array to hold multiple values if necessary
|
||||
if (isset($options['config-file'])) {
|
||||
if (isset($options['context-path'])) {
|
||||
$options['context-path'] = array_merge(array($options['config-file']), is_array($options['context-path']) ? $options['context-path'] : array($options['context-path']));
|
||||
}
|
||||
else {
|
||||
$options['context-path'] = $options['config-file'];
|
||||
}
|
||||
}
|
||||
|
||||
// Take out $aliases and $command_specific options
|
||||
drush_set_config_special_contexts($options);
|
||||
|
||||
drush_set_context($context, $options);
|
||||
|
||||
// Instruct core not to store queries since we are not outputting them.
|
||||
// Don't run poormanscron during drush request (D7+).
|
||||
$defaults = array(
|
||||
'dev_query' => FALSE,
|
||||
'cron_safe_threshold' => 0,
|
||||
);
|
||||
foreach ($defaults as $key => $value) {
|
||||
// This can be overridden by a command or a drushrc file if needed.
|
||||
if (!isset($drush_conf_override[$key])) {
|
||||
$drush_conf_override[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow the drushrc.php file to override $conf settings.
|
||||
* This is a separate variable because the $conf array gets
|
||||
* initialized to an empty array, in the drupal bootstrap process,
|
||||
* and changes in settings.php would wipe out the drushrc.php settings.
|
||||
*/
|
||||
if (!empty($override)) {
|
||||
$drush_conf_override = array_merge($drush_conf_override, $override);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* There are certain options such as 'site-aliases' and 'command-specific'
|
||||
* that must be merged together if defined in multiple drush configuration
|
||||
* files. If we did not do this merge, then the last configuration file
|
||||
* that defined any of these properties would overwrite all of the options
|
||||
* that came before in previously-loaded configuration files. We place
|
||||
* all of them into their own context so that this does not happen.
|
||||
*/
|
||||
function drush_set_config_special_contexts(&$options) {
|
||||
if (isset($options)) {
|
||||
$has_command_specific = array_key_exists('command-specific', $options);
|
||||
// Change the keys of the site aliases from 'alias' to '@alias'
|
||||
if (array_key_exists('site-aliases', $options)) {
|
||||
$user_aliases = $options['site-aliases'];
|
||||
$options['site-aliases'] = array();
|
||||
foreach ($user_aliases as $alias_name => $alias_value) {
|
||||
if (substr($alias_name,0,1) != '@') {
|
||||
$alias_name = "@$alias_name";
|
||||
}
|
||||
$options['site-aliases'][$alias_name] = $alias_value;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy site aliases and command-specific options into their
|
||||
// appropriate caches.
|
||||
$special_contexts = drush_get_special_keys();
|
||||
foreach ($special_contexts as $option_name) {
|
||||
if (isset($options[$option_name])) {
|
||||
$cache =& drush_get_context($option_name);
|
||||
$cache = array_merge($cache, $options[$option_name]);
|
||||
unset($options[$option_name]);
|
||||
}
|
||||
}
|
||||
// If command-specific options were set and if we already have
|
||||
// a command, then apply the command-specific options immediately.
|
||||
if ($has_command_specific) {
|
||||
drush_command_default_options();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a specific context.
|
||||
*
|
||||
* @param context
|
||||
* Any of the default defined contexts.
|
||||
* @param value
|
||||
* The value to store in the context
|
||||
*
|
||||
* @return
|
||||
* An associative array of the settings specified in the request context.
|
||||
*/
|
||||
function drush_set_context($context, $value) {
|
||||
$cache =& drush_get_context($context);
|
||||
$cache = $value;
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a specific context, or the whole context cache
|
||||
*
|
||||
* This function provides a storage mechanism for any information
|
||||
* the currently running process might need to communicate.
|
||||
*
|
||||
* This avoids the use of globals, and constants.
|
||||
*
|
||||
* Functions that operate on the context cache, can retrieve a reference
|
||||
* to the context cache using :
|
||||
* $cache = &drush_get_context($context);
|
||||
*
|
||||
* This is a private function, because it is meant as an internal
|
||||
* generalized API for writing static cache functions, not as a general
|
||||
* purpose function to be used inside commands.
|
||||
*
|
||||
* Code that modifies the reference directly might have unexpected consequences,
|
||||
* such as modifying the arguments after they have already been parsed and dispatched
|
||||
* to the callbacks.
|
||||
*
|
||||
* @param context
|
||||
* Optional. Any of the default defined contexts.
|
||||
*
|
||||
* @return
|
||||
* If context is not supplied, the entire context cache will be returned.
|
||||
* Otherwise only the requested context will be returned.
|
||||
* If the context does not exist yet, it will be initialized to an empty array.
|
||||
*/
|
||||
function &drush_get_context($context = NULL, $default = NULL) {
|
||||
static $cache = array();
|
||||
if (!is_null($context)) {
|
||||
if (!isset($cache[$context])) {
|
||||
$default = !is_null($default) ? $default : array();
|
||||
$cache[$context] = $default;
|
||||
}
|
||||
return $cache[$context];
|
||||
}
|
||||
return $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the arguments passed to the drush.php script.
|
||||
*
|
||||
* This function will set the 'arguments' context of the current running script.
|
||||
*
|
||||
* When initially called by drush_parse_args, the entire list of arguments will
|
||||
* be populated. Once the command is dispatched, this will be set to only the remaining
|
||||
* arguments to the command (i.e. the command name is removed).
|
||||
*
|
||||
* @param arguments
|
||||
* Command line arguments, as an array.
|
||||
*/
|
||||
function drush_set_arguments($arguments) {
|
||||
drush_set_context('arguments', $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the arguments passed to the drush.php script.
|
||||
*
|
||||
* When drush_set_arguments is initially called by drush_parse_args,
|
||||
* the entire list of arguments will be populated.
|
||||
* Once the command has been dispatched, this will be return only the remaining
|
||||
* arguments to the command.
|
||||
*/
|
||||
function drush_get_arguments() {
|
||||
return drush_get_context('arguments');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the command being executed.
|
||||
*
|
||||
* Drush_dispatch will set the correct command based on it's
|
||||
* matching of the script arguments retrieved from drush_get_arguments
|
||||
* to the implemented commands specified by drush_get_commands.
|
||||
*
|
||||
* @param
|
||||
* A numerically indexed array of command components.
|
||||
*/
|
||||
function drush_set_command($command) {
|
||||
drush_set_context('command', $command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the command being executed.
|
||||
*
|
||||
*
|
||||
*/
|
||||
function drush_get_command() {
|
||||
return drush_get_context('command');
|
||||
}
|
||||
/**
|
||||
* Get the value for an option.
|
||||
*
|
||||
* If the first argument is an array, then it checks whether one of the options
|
||||
* exists and return the value of the first one found. Useful for allowing both
|
||||
* -h and --host-name
|
||||
*
|
||||
* @param option
|
||||
* The name of the option to get
|
||||
* @param default
|
||||
* Optional. The value to return if the option has not been set
|
||||
* @param context
|
||||
* Optional. The context to check for the option. If this is set, only this context will be searched.
|
||||
*/
|
||||
function drush_get_option($option, $default = NULL, $context = NULL) {
|
||||
$value = NULL;
|
||||
|
||||
if ($context) {
|
||||
// We have a definite context to check for the presence of an option.
|
||||
$value = _drush_get_option($option, drush_get_context($context));
|
||||
}
|
||||
else {
|
||||
// We are not checking a specific context, so check them in a predefined order of precedence.
|
||||
$contexts = drush_context_names();
|
||||
|
||||
foreach ($contexts as $context) {
|
||||
$value = _drush_get_option($option, drush_get_context($context));
|
||||
|
||||
if ($value !== NULL) {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($value !== NULL) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for an option and return it as a list. If the
|
||||
* option in question is passed on the command line, its value should
|
||||
* be a comma-separated list (e.g. --flag=1,2,3). If the option
|
||||
* was set in a drushrc.php file, then its value may be either a
|
||||
* comma-separated list or an array of values (e.g. $option['flag'] = array('1', '2', '3')).
|
||||
*
|
||||
* @param option
|
||||
* The name of the option to get
|
||||
* @param default
|
||||
* Optional. The value to return if the option has not been set
|
||||
* @param context
|
||||
* Optional. The context to check for the option. If this is set, only this context will be searched.
|
||||
*/
|
||||
function drush_get_option_list($option, $default = array(), $context = NULL) {
|
||||
$result = drush_get_option($option, $default, $context);
|
||||
|
||||
if (!is_array($result)) {
|
||||
$result = explode(',', $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for an option, but first checks the provided option overrides.
|
||||
*
|
||||
* The feature of drush_get_option that allows a list of option names
|
||||
* to be passed in an array is NOT supported.
|
||||
*
|
||||
* @param option_overrides
|
||||
* An array to check for values before calling drush_get_option.
|
||||
* @param option
|
||||
* The name of the option to get.
|
||||
* @param default
|
||||
* Optional. The value to return if the option has not been set.
|
||||
* @param context
|
||||
* Optional. The context to check for the option. If this is set, only this context will be searched.
|
||||
*
|
||||
*/
|
||||
function drush_get_option_override($option_overrides, $option, $value = NULL, $context = NULL) {
|
||||
if (array_key_exists($option, $option_overrides)) {
|
||||
return $option_overrides[$option];
|
||||
}
|
||||
else {
|
||||
return drush_get_option($option, $value, $context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the values for an option in every context.
|
||||
*
|
||||
* @param option
|
||||
* The name of the option to get
|
||||
* @return
|
||||
* An array whose key is the context name and value is
|
||||
* the specific value for the option in that context.
|
||||
*/
|
||||
function drush_get_context_options($option, $flatten = FALSE) {
|
||||
$result = array();
|
||||
|
||||
$contexts = drush_context_names();
|
||||
foreach ($contexts as $context) {
|
||||
$value = _drush_get_option($option, drush_get_context($context));
|
||||
|
||||
if ($value !== NULL) {
|
||||
if ($flatten && is_array($value)) {
|
||||
$result = array_merge($value, $result);
|
||||
}
|
||||
else {
|
||||
$result[$context] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a collapsed list of all options
|
||||
*/
|
||||
function drush_get_merged_options() {
|
||||
$contexts = drush_context_names();
|
||||
$cache = drush_get_context();
|
||||
$result = array();
|
||||
foreach (array_reverse($contexts) as $context) {
|
||||
if (array_key_exists($context, $cache)) {
|
||||
$result = array_merge($result, $cache[$context]);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to recurse through possible option names
|
||||
*/
|
||||
function _drush_get_option($option, $context) {
|
||||
if (is_array($option)) {
|
||||
foreach ($option as $current) {
|
||||
if (array_key_exists($current, $context)) {
|
||||
return $context[$current];
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (array_key_exists($option, $context)) {
|
||||
return $context[$option];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an option in one of the option contexts.
|
||||
*
|
||||
* @param option
|
||||
* The option to set.
|
||||
* @param value
|
||||
* The value to set it to.
|
||||
* @param context
|
||||
* Optional. Which context to set it in.
|
||||
* @return
|
||||
* The value parameter. This allows for neater code such as
|
||||
* $myvalue = drush_set_option('http_host', $_SERVER['HTTP_HOST']);
|
||||
* Without having to constantly type out the value parameter.
|
||||
*/
|
||||
function drush_set_option($option, $value, $context = 'process') {
|
||||
$cache =& drush_get_context($context);
|
||||
$cache[$option] = $value;
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* A small helper function to set the value in the default context
|
||||
*/
|
||||
function drush_set_default($option, $value) {
|
||||
return drush_set_option($option, $value, 'default');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a setting from a specific context.
|
||||
*
|
||||
* @param
|
||||
* Option to be unset
|
||||
* @param
|
||||
* Context in which to unset the value in.
|
||||
*/
|
||||
function drush_unset_option($option, $context = NULL) {
|
||||
if ($context != NULL) {
|
||||
$cache =& drush_get_context($context);
|
||||
if (array_key_exists($option, $cache)) {
|
||||
unset($cache[$option]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$contexts = drush_context_names();
|
||||
|
||||
foreach ($contexts as $context) {
|
||||
drush_unset_option($option, $context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the settings in a specific context to the applicable configuration file
|
||||
* This is useful is you want certain settings to be available automatically the next time a command is executed.
|
||||
*
|
||||
* @param $context
|
||||
* The context to save
|
||||
*/
|
||||
function drush_save_config($context) {
|
||||
$filename = _drush_config_file($context);
|
||||
|
||||
if ($filename) {
|
||||
$cache = drush_get_context($context);
|
||||
|
||||
$fp = fopen($filename, "w+");
|
||||
if (!$fp) {
|
||||
return drush_set_error('DRUSH_PERM_ERROR', dt('Drushrc (!filename) could not be written', array('!filename' => $filename)));
|
||||
}
|
||||
else {
|
||||
fwrite($fp, "<?php\n");
|
||||
$timestamp = mktime();
|
||||
foreach ($cache as $key => $value) {
|
||||
$line = "\n\$options['$key'] = ". var_export($value, TRUE) .';';
|
||||
fwrite($fp, $line);
|
||||
}
|
||||
fwrite($fp, "\n");
|
||||
fclose($fp);
|
||||
drush_log(dt('Drushrc file (!filename) was written successfully', array('!filename' => $filename)));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user