first import
This commit is contained in:
597
sites/all/modules/drush/includes/context.inc
Normal file
597
sites/all/modules/drush/includes/context.inc
Normal file
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user