X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=blobdiff_plain;f=vendor%2Fdrush%2Fdrush%2Fincludes%2Fcomplete.inc;fp=vendor%2Fdrush%2Fdrush%2Fincludes%2Fcomplete.inc;h=0000000000000000000000000000000000000000;hp=ba36b501eaadaaf9839d9b5c33857dbc96ee031b;hb=af6d1fb995500ae68849458ee10d66abbdcfb252;hpb=680c79a86e3ed402f263faeac92e89fb6d9edcc0 diff --git a/vendor/drush/drush/includes/complete.inc b/vendor/drush/drush/includes/complete.inc deleted file mode 100644 index ba36b501e..000000000 --- a/vendor/drush/drush/includes/complete.inc +++ /dev/null @@ -1,586 +0,0 @@ -. The shell completion scripts should call - * "drush complete ", where is the full command line, which we take - * as input and use to produce a list of possible completions for the - * current/next word, separated by newlines. Typically, when multiple - * completions are returned the shell will display them to the user in a concise - * format - but when a single completion is returned it will autocomplete. - * - * We provide completion for site aliases, commands, shell aliases, options, - * engines and arguments. Displaying all of these when the last word has no - * characters yet is not useful, as there are too many items. Instead we filter - * the possible completions based on position, in a similar way to git. - * For example: - * - We only display site aliases and commands if one is not already present. - * - We only display options if the user has already entered a hyphen. - * - We only display global options before a command is entered, and we only - * display command specific options after the command (Drush itself does not - * care about option placement, but this approach keeps things more concise). - * - * Below is typical output of complete in different situations. Tokens in square - * brackets are optional, and [word] will filter available options that start - * with the same characters, or display all listed options if empty. - * drush --[word] : Output global options - * drush [word] : Output site aliases, sites, commands and shell aliases - * drush [@alias] [word] : Output commands - * drush [@alias] command [word] : Output command specific arguments - * drush [@alias] command --[word] : Output command specific options - * - * Because the purpose of autocompletion is to make the command line more - * efficient for users we need to respond quickly with the list of completions. - * To do this, we call drush_complete() early in the Drush bootstrap, and - * implement a simple caching system. - * - * To generate the list of completions, we set up the Drush environment as if - * the command was called on it's own, parse the command using the standard - * Drush functions, bootstrap the site (if any) and collect available - * completions from various sources. Because this can be somewhat slow, we cache - * the results. The cache strategy aims to balance accuracy and responsiveness: - * - We cache per site, if a site is available. - * - We generate (and cache) everything except arguments at the same time, so - * subsequent completions on the site don't need any bootstrap. - * - We generate and cache arguments on-demand, since these can often be - * expensive to generate. Arguments are also cached per-site. - * - * For argument completions, commandfiles can implement - * COMMANDFILE_COMMAND_complete() returning an array containing a key 'values' - * containing an array of all possible argument completions for that command. - * For example, return array('values' => array('aardvark', 'aardwolf')) offers - * the words 'aardvark' and 'aardwolf', or will complete to 'aardwolf' if the - * letters 'aardw' are already present. Since command arguments are cached, - * commandfiles can bootstrap a site or perform other somewhat time consuming - * activities to retrieve the list of possible arguments. Commands can also - * clear the cache (or just the "arguments" cache for their command) when the - * completion results have likely changed - see drush_complete_cache_clear(). - * - * Commandfiles can also return a special optional element in their array with - * the key 'files' that contains an array of patterns/flags for the glob() - * function. These are used to produce file and directory completions (the - * results of these are not cached, since this is a fast operation). - * See http://php.net/glob for details of valid patterns and flags. - * For example the following will complete the command arguments on all - * directories, as well as files ending in tar.gz: - * return array( - * 'files' => array( - * 'directories' => array( - * 'pattern' => '*', - * 'flags' => GLOB_ONLYDIR, - * ), - * 'tar' => array( - * 'pattern' => '*.tar.gz', - * ), - * ), - * ); - * - * To check completion results without needing to actually trigger shell - * completion, you can call this manually using a command like: - * - * drush --early=includes/complete.inc [--complete-debug] drush [@alias] [command]... - * - * If you want to simulate the results of pressing tab after a space (i.e. - * and empty last word, include '' on the end of your command: - * - * drush --early=includes/complete.inc [--complete-debug] drush '' - */ - -/** - * Produce autocomplete output. - * - * Determine position (is there a site-alias or command set, and are we trying - * to complete an option). Then produce a list of completions for the last word - * and output them separated by newlines. - */ -function drush_early_complete() { - // We use a distinct --complete-debug option to avoid unwanted debug messages - // being printed when users use this option for other purposes in the command - // they are trying to complete. - drush_set_option(LogLevel::DEBUG, FALSE); - if (drush_get_option('complete-debug', FALSE)) { - drush_set_context('DRUSH_DEBUG', TRUE); - } - // Set up as if we were running the command, and attempt to parse. - $argv = drush_complete_process_argv(); - if ($alias = drush_get_context('DRUSH_TARGET_SITE_ALIAS')) { - $set_sitealias_name = $alias; - $set_sitealias = drush_sitealias_get_record($alias); - } - - // Arguments have now had site-aliases and options removed, so we take the - // first item as our command. We need to know if the command is valid, so that - // we know if we are supposed to complete an in-progress command name, or - // arguments for a command. We do this by checking against our per-site cache - // of command names (which will only bootstrap if the cache needs to be - // regenerated), rather than drush_parse_command() which always requires a - // site bootstrap. - $arguments = drush_get_arguments(); - $set_command_name = NULL; - if (isset($arguments[0]) && in_array($arguments[0] . ' ', drush_complete_get('command-names'))) { - $set_command_name = $arguments[0]; - } - // We unset the command if it is "help" but that is not explicitly found in - // args, since Drush sets the command to "help" if no command is specified, - // which prevents completion of global options. - if ($set_command_name == 'help' && !array_search('help', $argv)) { - $set_command_name = NULL; - } - - // Determine the word we are trying to complete, and if it is an option. - $last_word = end($argv); - $word_is_option = FALSE; - if (!empty($last_word) && $last_word[0] == '-') { - $word_is_option = TRUE; - $last_word = ltrim($last_word, '-'); - } - - $completions = array(); - if (!$set_command_name) { - // We have no command yet. - if ($word_is_option) { - // Include global option completions. - $completions += drush_hyphenate_options(drush_complete_match($last_word, drush_complete_get('options'))); - } - else { - if (empty($set_sitealias_name)) { - // Include site alias completions. - $completions += drush_complete_match($last_word, drush_complete_get('site-aliases')); - } - // Include command completions. - $completions += drush_complete_match($last_word, drush_complete_get('command-names')); - } - } - else { - if ($last_word == $set_command_name) { - // The user just typed a valid command name, but we still do command - // completion, as there may be other commands that start with the detected - // command (e.g. "make" is a valid command, but so is "make-test"). - // If there is only the single matching command, this will include in the - // completion list so they get a space inserted, confirming it is valid. - $completions += drush_complete_match($last_word, drush_complete_get('command-names')); - } - else if ($word_is_option) { - // Include command option completions. - $completions += drush_hyphenate_options(drush_complete_match($last_word, drush_complete_get('options', $set_command_name))); - } - else { - // Include command argument completions. - $argument_completion = drush_complete_get('arguments', $set_command_name); - if (isset($argument_completion['values'])) { - $completions += drush_complete_match($last_word, $argument_completion['values']); - } - if (isset($argument_completion['files'])) { - $completions += drush_complete_match_file($last_word, $argument_completion['files']); - } - } - } - - if (!empty($completions)) { - sort($completions); - return implode("\n", $completions); - } - return TRUE; -} - -/** - * This function resets the raw arguments so that Drush can parse the command as - * if it was run directly. The shell complete command passes the - * full command line as an argument, and the --early and --complete-debug - * options have to come before that, and the "drush" bash script will add a - * --php option on the end, so we end up with something like this: - * - * /path/to/drush.php --early=includes/complete.inc [--complete-debug] drush [@alias] [command]... --php=/usr/bin/php - * - * Note that "drush" occurs twice, and also that the second occurrence could be - * an alias, so we can't easily use it as to detect the start of the actual - * command. Hence our approach is to remove the initial "drush" and then any - * options directly following that - what remains is then the command we need - * to complete - i.e.: - * - * drush [@alias] [command]... - * - * Note that if completion is initiated following a space an empty argument is - * added to argv. So in that case argv looks something like this: - * array ( - * '0' => '/path/to/drush.php', - * '1' => '--early=includes/complete.inc', - * '2' => 'drush', - * '3' => 'topic', - * '4' => '', - * '5' => '--php=/usr/bin/php', - * ); - * - * @return $args - * Array of arguments (argv), excluding the initial command and options - * associated with the complete call. - * array ( - * '0' => 'drush', - * '1' => 'topic', - * '2' => '', - * ); - */ -function drush_complete_process_argv() { - $argv = drush_get_context('argv'); - // Remove the first argument, which will be the "drush" command. - array_shift($argv); - while (substr($arg = array_shift($argv), 0, 2) == '--') { - // We remove all options, until we get to a non option, which - // marks the start of the actual command we are trying to complete. - } - // Replace the initial argument. - array_unshift($argv, $arg); - // Remove the --php option at the end if exists (added by the "drush" shell - // script that is called when completion is requested). - if (substr(end($argv), 0, 6) == '--php=') { - array_pop($argv); - } - drush_set_context('argv', $argv); - drush_set_command(NULL); - // Reparse arguments, site alias, and command. - drush_parse_args(); - // Ensure the base environment is configured, so tests look in the correct - // places. - _drush_preflight_base_environment(); - // Check for and record any site alias. - drush_sitealias_check_arg(); - drush_sitealias_check_site_env(); - // We might have just changed our root--run drush_select_bootstrap_class() again. - $bootstrap = drush_select_bootstrap_class(); - - // Return the new argv for easy reference. - return $argv; -} - -/** - * Retrieves the appropriate list of candidate completions, then filters this - * list using the last word that we are trying to complete. - * - * @param string $last_word - * The last word in the argument list (i.e. the subject of completion). - * @param array $values - * Array of possible completion values to filter. - * - * @return array - * Array of candidate completions that start with the same characters as the - * last word. If the last word is empty, return all candidates. - */ -function drush_complete_match($last_word, $values) { - // Using preg_grep appears to be faster that strpos with array_filter/loop. - return preg_grep('/^' . preg_quote($last_word, '/') . '/', $values); -} - -/** - * Retrieves the appropriate list of candidate file/directory completions, - * filtered by the last word that we are trying to complete. - * - * @param string $last_word - * The last word in the argument list (i.e. the subject of completion). - * @param array $files - * Array of file specs, each with a pattern and flags subarray. - * - * @return array - * Array of candidate file/directory completions that start with the same - * characters as the last word. If the last word is empty, return all - * candidates. - */ -function drush_complete_match_file($last_word, $files) { - $return = array(); - if ($last_word[0] == '~') { - // Complete does not do tilde expansion, so we do it here. - // We shell out (unquoted) to expand the tilde. - drush_shell_exec('echo ' . $last_word); - return drush_shell_exec_output(); - } - - $dir = ''; - if (substr($last_word, -1) == '/' && is_dir($last_word)) { - // If we exactly match a trailing directory, then we use that as the base - // for the listing. We only do this if a trailing slash is present, since at - // this stage it is still possible there are other directories that start - // with this string. - $dir = $last_word; - } - else { - // Otherwise we discard the last part of the path (this is matched against - // the list later), and use that as our base. - $dir = dirname($last_word); - if (empty($dir) || $dir == '.' && $last_word != '.' && substr($last_word, 0, 2) != './') { - // We are looking at the current working directory, so unless the user is - // actually specifying a leading dot we leave the path empty. - $dir = ''; - } - else { - // In all other cases we need to add a trailing slash. - $dir .= '/'; - } - } - - foreach ($files as $spec) { - // We always include GLOB_MARK, as an easy way to detect directories. - $flags = GLOB_MARK; - if (isset($spec['flags'])) { - $flags = $spec['flags'] | GLOB_MARK; - } - $listing = glob($dir . $spec['pattern'], $flags); - $return = array_merge($return, drush_complete_match($last_word, $listing)); - } - // If we are returning a single item (which will become part of the final - // command), we need to use the full path, and we need to escape it - // appropriately. - if (count($return) == 1) { - // Escape common shell metacharacters (we don't use escapeshellarg as it - // single quotes everything, even when unnecessary). - $item = array_pop($return); - $item = preg_replace('/[ |&;()<>]/', "\\\\$0", $item); - if (substr($item, -1) !== '/') { - // Insert a space after files, since the argument is complete. - $item = $item . ' '; - } - $return = array($item); - } - else { - $firstchar = TRUE; - if ($last_word[0] == '/') { - // If we are working with absolute paths, we need to check if the first - // character of all the completions matches. If it does, then we pass a - // full path for each match, so the shell completes as far as it can, - // matching the behaviour with relative paths. - $pos = strlen($last_word); - foreach ($return as $id => $item) { - if ($item[$pos] !== $return[0][$pos]) { - $firstchar = FALSE; - continue; - } - } - } - foreach ($return as $id => $item) { - // For directories we leave the path alone. - $slash_pos = strpos($last_word, '/'); - if ($slash_pos === 0 && $firstchar) { - // With absolute paths where completions share initial characters, we - // pass in a resolved path. - $return[$id] = realpath($item); - } - else if ($slash_pos !== FALSE && $dir != './') { - // For files, we pass only the file name, ignoring the false match when - // the user is using a single dot relative path. - $return[$id] = basename($item); - } - } - } - return $return; -} - -/** - * Simple helper function to ensure options are properly hyphenated before we - * return them to the user (we match against the non-hyphenated versions - * internally). - * - * @param array $options - * Array of unhyphenated option names. - * - * @return array - * Array of hyphenated option names. - */ -function drush_hyphenate_options($options) { - foreach ($options as $key => $option) { - $options[$key] = '--' . ltrim($option, '--'); - } - return $options; -} - -/** - * Retrieves from cache, or generates a listing of completion candidates of a - * specific type (and optionally, command). - * - * @param string $type - * String indicating type of completions to return. - * See drush_complete_rebuild() for possible keys. - * @param string $command - * An optional command name if command specific completion is needed. - * - * @return array - * List of candidate completions. - */ -function drush_complete_get($type, $command = NULL) { - static $complete; - if (empty($command)) { - // Quick return if we already have a complete static cache. - if (!empty($complete[$type])) { - return $complete[$type]; - } - // Retrieve global items from a non-command specific cache, or rebuild cache - // if needed. - $cache = drush_cache_get(drush_complete_cache_cid($type), 'complete'); - if (isset($cache->data)) { - return $cache->data; - } - $complete = drush_complete_rebuild(); - return $complete[$type]; - } - // Retrieve items from a command specific cache. - $cache = drush_cache_get(drush_complete_cache_cid($type, $command), 'complete'); - if (isset($cache->data)) { - return $cache->data; - } - // Build argument cache - built only on demand. - if ($type == 'arguments') { - return drush_complete_rebuild_arguments($command); - } - // Rebuild cache of general command specific items. - if (empty($complete)) { - $complete = drush_complete_rebuild(); - } - if (!empty($complete['commands'][$command][$type])) { - return $complete['commands'][$command][$type]; - } - return array(); -} - -/** - * Rebuild and cache completions for everything except command arguments. - * - * @return array - * Structured array of completion types, commands and candidate completions. - */ -function drush_complete_rebuild() { - $complete = array(); - // Bootstrap to the site level (if possible) - commands may need to check - // the bootstrap level, and perhaps bootstrap higher in extraordinary cases. - drush_bootstrap_max(DRUSH_BOOTSTRAP_DRUPAL_CONFIGURATION); - $commands = drush_get_commands(); - foreach ($commands as $command_name => $command) { - // Add command options and suboptions. - $options = array_keys($command['options']); - foreach ($command['sub-options'] as $option => $sub_options) { - $options = array_merge($options, array_keys($sub_options)); - } - $complete['commands'][$command_name]['options'] = $options; - } - // We treat shell aliases as commands for the purposes of completion. - $complete['command-names'] = array_merge(array_keys($commands), array_keys(drush_get_context('shell-aliases', array()))); - $site_aliases = _drush_sitealias_all_list(); - // TODO: Figure out where this dummy @0 alias is introduced. - unset($site_aliases['@0']); - $complete['site-aliases'] = array_keys($site_aliases); - $complete['options'] = array_keys(drush_get_global_options()); - - // We add a space following all completes. Eventually there may be some - // items (e.g. options that we know need values) where we don't add a space. - array_walk_recursive($complete, 'drush_complete_trailing_space'); - drush_complete_cache_set($complete); - return $complete; -} - -/** - * Helper callback function that adds a trailing space to completes in an array. - */ -function drush_complete_trailing_space(&$item, $key) { - if (!is_array($item)) { - $item = (string)$item . ' '; - } -} - -/** - * Rebuild and cache completions for command arguments. - * - * @param string $command - * A specific command to retrieve and cache arguments for. - * - * @return array - * Structured array of candidate completion arguments, keyed by the command. - */ -function drush_complete_rebuild_arguments($command) { - // Bootstrap to the site level (if possible) - commands may need to check - // the bootstrap level, and perhaps bootstrap higher in extraordinary cases. - drush_bootstrap_max(DRUSH_BOOTSTRAP_DRUPAL_SITE); - $commands = drush_get_commands(); - $command_info = $commands[$command]; - if ($callback = $command_info['annotated-command-callback']) { - list($classname, $method) = $callback; - $commandInfo = new CommandInfo($classname, $method); - if ($callable = $commandInfo->getAnnotation('complete')) { - $result = call_user_func($callable); - } - } - else { - $hook = str_replace("-", "_", $command_info['command-hook']); - $result = drush_command_invoke_all($hook . '_complete'); - } - if (isset($result['values'])) { - // We add a space following all completes. Eventually there may be some - // items (e.g. comma separated arguments) where we don't add a space. - array_walk($result['values'], 'drush_complete_trailing_space'); - } - - $complete = array( - 'commands' => array( - $command => array( - 'arguments' => $result, - ) - ) - ); - drush_complete_cache_set($complete); - return $complete['commands'][$command]['arguments']; -} - -/** - * Stores caches for completions. - * - * @param $complete - * A structured array of completions, keyed by type, including a 'commands' - * type that contains all commands with command specific completions keyed by - * type. The array does not need to include all types - used by - * drush_complete_rebuild_arguments(). - */ -function drush_complete_cache_set($complete) { - foreach ($complete as $type => $values) { - if ($type == 'commands') { - foreach ($values as $command_name => $command) { - foreach ($command as $command_type => $command_values) { - drush_cache_set(drush_complete_cache_cid($command_type, $command_name), $command_values, 'complete', DRUSH_CACHE_TEMPORARY); - } - } - } - else { - drush_cache_set(drush_complete_cache_cid($type), $values, 'complete', DRUSH_CACHE_TEMPORARY); - } - } -} - -/** - * Generate a cache id. - * - * @param $type - * The completion type. - * @param $command - * The command name (optional), if completions are command specific. - * - * @return string - * Cache id. - */ -function drush_complete_cache_cid($type, $command = NULL) { - // For per-site caches, we include the site root and uri/path in the cache id - // hash. These are quick to determine, and prevents a bootstrap to site just - // to get a validated root and URI. Because these are not validated, there is - // the possibility of cache misses/ but they should be rare, since sites are - // normally referred to the same way (e.g. a site alias, or using the current - // directory), at least within a single command completion session. - // We also static cache them, since we may get differing results after - // bootstrap, which prevents the caches from being found on the next call. - static $root, $site; - if (empty($root)) { - $root = drush_get_option(array('r', 'root'), drush_locate_root()); - $site = drush_get_option(array('l', 'uri'), drush_site_path()); - } - return drush_get_cid('complete', array(), array($type, $command, $root, $site)); -}