function drush_sitealias_evaluate_path

8.0.x drush_sitealias_evaluate_path($path, &$additional_options, $local_only = FALSE, $os = NULL, $command_specific_prefix = '')
6.x drush_sitealias_evaluate_path($path, &$additional_options, $local_only = FALSE, $os = NULL, $command_specific_prefix = '')
7.x drush_sitealias_evaluate_path($path, &$additional_options, $local_only = FALSE, $os = NULL, $command_specific_prefix = '')
3.x drush_sitealias_evaluate_path($path, &$additional_options)
4.x drush_sitealias_evaluate_path($path, &$additional_options, $local_only = FALSE)
5.x drush_sitealias_evaluate_path($path, &$additional_options, $local_only = FALSE, $os = NULL, $command_specific_prefix = '')
master drush_sitealias_evaluate_path($path, &$additional_options, $local_only = FALSE, $os = NULL, $command_specific_prefix = '')

Evaluate a path from its shorthand form to a literal path usable by rsync.

A path is "machine:/path" or "machine:path" or "/path" or "path". 'machine' might instead be an alias record, or the name of a site in the 'sites' folder. 'path' might be (or contain) '%root' or some other path alias. This function will examine all components of the path and evaluate them as necessary to come to the final path.


path: The path to evaluate

additional_options: An array of options that overrides whatever was passed in on the command line (like the 'process' context, but only for the scope of this one call).

local_only: If TRUE, force an error if the provided path points to a remote machine.

os: This should be the local system os, unless evaluate path is being called for rsync, in which case it should be "CWRSYNC" if cwrsync is being used, or "rsync" to automatically select between "LOCAL" and "CWRSYNC" based on the platform.

Return value

The site record for the machine specified in the path, if any, with the path to pass to rsync (including the machine specifier) in the 'evaluated-path' item.

3 calls to drush_sitealias_evaluate_path()
drush_config_export_validate in commands/core/
drush_core_rsync in commands/core/
A command callback.
_drush_core_directory in commands/core/
Given a target (e.g. @site:%modules), return the evaluated directory path.


includes/, line 1908
The site alias API.


function drush_sitealias_evaluate_path($path, &$additional_options, $local_only = FALSE, $os = NULL, $command_specific_prefix = '') {
  $site_alias_settings = array();
  $path_aliases = array();
  $remote_user = '';

  $preflight = _drush_sitealias_preflight_path($path);
  if (!isset($preflight)) {
    return NULL;

  $alias = $preflight['alias'];
  $path = $preflight['path'];
  $machine = $preflight['machine'];

  if (isset($alias)) {
    // Note that the alias settings may have an 'os' component, but we do
    // not want to use it here.  The paths passed to rsync should always be
    // escaped per the LOCAL rules, without regard to the remote platform type.
    $site_alias_settings = drush_sitealias_get_record($alias);
    if (!empty($command_specific_prefix)) {
      drush_sitealias_command_default_options($site_alias_settings, $command_specific_prefix);

  if (!empty($site_alias_settings)) {
    if ($local_only && array_key_exists('remote-host', $site_alias_settings)) {
      return drush_set_error('DRUSH_REMOTE_SITE_IN_LOCAL_CONTEXT', dt("A remote site alias was used in a context where only a local alias is appropriate."));

    // Apply any options from this alias that might affect our rsync

    // Use 'remote-host' from settings if available; otherwise site is local
    if (array_key_exists('remote-host', $site_alias_settings) && !drush_is_local_host($site_alias_settings['remote-host'])) {
      $machine = drush_remote_host($site_alias_settings);
    else {
      $machine = '';
  else {
    // Strip the machine portion of the path if the
    // alias points to the local machine.
    if (drush_is_local_host($machine)) {
      $machine = '';
    else {
      $machine = "$remote_user$machine";

  // TOD:  The code below is a little rube-goldberg-ish, and needs to be
  // reworked.  core-rsync will call this function twice: once to
  // evaluate the destination, and then again to evaluate the source.  Things
  // get odd with --exclude-paths, especially in conjunction with command-specific
  // and the --exclude-files option.  @see testCommandSpecific()

  // If the --exclude-other-sites option is specified, then
  // convert that into --include-paths='%site' and --exclude-sites.
  if (drush_get_option_override($additional_options, 'exclude-other-sites', FALSE) && !drush_get_context('exclude-other-sites-processed', FALSE)) {
    $include_path_option = drush_get_option_override($additional_options, 'include-paths', '');
    $additional_options['include-paths'] = '%site';
    if (!empty($include_path_option)) {
      // We use PATH_SEPARATOR here because we are later going to explicitly explode() this variable using PATH_SEPARATOR.
      $additional_options['include-paths'] .= PATH_SEPARATOR . $include_path_option;
    $additional_options['exclude-sites'] = TRUE;
    drush_set_context('exclude-other-sites-processed', TRUE);
  else {
  // If the --exclude-files option is specified, then
  // convert that into --exclude-paths='%files'.
  if (drush_get_option_override($additional_options, 'exclude-files', FALSE) && !drush_get_option_override($additional_options, 'exclude-files-processed', FALSE, 'process')) {
    $exclude_path_option = drush_get_option_override($additional_options, 'exclude-paths', '');
    $additional_options['exclude-paths'] = '%files';
    if (!empty($exclude_path_option)) {
      // We use PATH_SEPARATOR here because we are later going to explicitly explode() this variable using PATH_SEPARATOR.
      $additional_options['exclude-paths'] .= PATH_SEPARATOR . $exclude_path_option;
    $additional_options['exclude-files-processed'] = TRUE;
  else {

  // If there was no site specification given, and the
  // machine is local, then try to look
  // up an alias record for the default drush site.
  if (empty($site_alias_settings) && empty($machine)) {
    $drush_uri = drush_get_context('DRUSH_SELECTED_URI', 'default');
    $site_alias_settings = drush_sitealias_get_record($drush_uri);

  // Always add transient defaults

  // The $resolve_path variable is used by drush_sitealias_resolve_path_references
  // to test to see if there are any path references such as %site or %files
  // in it, so that resolution is only done if the path alias is referenced.
  // Therefore, we can concatenate without worrying too much about the structure of
  // this variable's contents.
  $include_path = drush_get_option_override($additional_options, 'include-paths', '');
  $exclude_path = drush_get_option_override($additional_options, 'exclude-paths', '');
  if (is_array($include_path)) {
    $include_path = implode('/', $include_path);
  if (is_array($exclude_path)) {
    $include_path = implode('/', $exclude_path);
  $resolve_path = "$path/$include_path/$exclude_path";
  // Resolve path aliases such as %files, if any exist in the path
  if (!empty($resolve_path)) {
    drush_sitealias_resolve_path_references($site_alias_settings, $resolve_path);

  if (array_key_exists('path-aliases', $site_alias_settings)) {
    $path_aliases = $site_alias_settings['path-aliases'];

  // Get the 'root' setting from the alias; if it does not
  // exist, then get the root from the bootstrapped site.
  if (array_key_exists('root', $site_alias_settings)) {
    $drupal_root = $site_alias_settings['root'];
  else {
    $drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT');
  if (empty($drupal_root)) {
    $drupal_root = '';
  else {
    // Add a slash to the end of the drupal root, as below.
    $drupal_root = drush_trim_path($drupal_root) . "/";
  $full_path_aliases = $path_aliases;
  foreach ($full_path_aliases as $key => $value) {
    // Expand all relative path aliases to be based off of the Drupal root
    if (!drush_is_absolute_path($value, "LOCAL") && ($key != '%root')) {
      $full_path_aliases[$key] = $drupal_root . $value;
    // We do not want slashes on the end of our path aliases.
    $full_path_aliases[$key] = drush_trim_path($full_path_aliases[$key]);

  // Fill in path aliases in the path, the include path and the exclude path.
  $path = str_replace(array_keys($full_path_aliases), array_values($full_path_aliases), $path);
  if (!empty($include_path)) {
    drush_set_option('include-paths', str_replace(array_keys($path_aliases), array_values($path_aliases), $include_path));
  if (!empty($exclude_path)) {
    drush_set_option('exclude-paths', str_replace(array_keys($path_aliases), array_values($path_aliases), $exclude_path));
  // Next make the rsync path, which includes the machine
  // and path components together.
  // First make empty paths or relative paths start from the drupal root.
  if (empty($path) || (!drush_is_absolute_path($path, "LOCAL"))) {
    $path = $drupal_root . $path;
  // When calculating a path for use with rsync, we must correct
  // absolute paths in the form c:\path when cwrsync is in use.
  $path = drush_correct_absolute_path_for_exec($path, $os);

  // If there is a $machine component, to the path, then
  // add it to the beginning
  $evaluated_path = drush_escapeshellarg($path, $os);
  if (!empty($machine)) {
    $evaluated_path = $machine . ':' . $evaluated_path;

  // Add our result paths:
  //    evaluated-path:         machine:/path
  //    server-component:       machine
  //    path-component:         :/path
  //    path:                   /path
  //    user-path:              path (as specified in input parameter)
  $site_alias_settings['evaluated-path'] = $evaluated_path;
  if (!empty($machine)) {
    $site_alias_settings['server-component'] = $machine;
  $site_alias_settings['path-component'] = (!empty($path) ? ':' . $path : '');
  $site_alias_settings['path'] = $path;
  $site_alias_settings['user-path'] = $preflight['path'];

  return $site_alias_settings;