From 1201d727192daf88117c77d7b36cd443ab7dc129 Mon Sep 17 00:00:00 2001
From: florenttorregrosa <florenttorregrosa@2388214.no-reply.drupal.org>
Date: Thu, 19 Jan 2017 18:23:47 +0100
Subject: [PATCH] Issue #2650290 by SocialNicheGuru, colan, ergonlogic, dman,
 helmo, memtkmcc, Grimreaper: Cannot find profiles beneath top-level
 directories

---
 platform/provision_drupal.drush.inc | 172 ++++++++++++++++++++++--------------
 1 file changed, 106 insertions(+), 66 deletions(-)

diff --git a/platform/provision_drupal.drush.inc b/platform/provision_drupal.drush.inc
index 389486e..a223a14 100644
--- a/platform/provision_drupal.drush.inc
+++ b/platform/provision_drupal.drush.inc
@@ -377,97 +377,137 @@ function _provision_drupal_rebuild_caches() {
  */
 function _provision_find_profiles() {
   $profiles = array();
+  $profiles_subdirs = array(
+    'required' => array(),
+    'optional' => array(),
+  );
 
   if (drush_drupal_major_version() >= 8) {
     include_once('core/includes/install.inc');
-    $profiles_subdirs[] = "./core/profiles";
-    $profiles_subdirs[] = "./profiles";
+    $profiles_subdirs['required'][] = "./core/profiles";
+    $profiles_subdirs['required'][] = "./profiles";
+    $profiles_subdirs['optional'][] = "./profiles/contrib";
+    $profiles_subdirs['optional'][] = "./profiles/custom";
   }
   else {
     include_once('includes/install.inc');
-    $profiles_subdirs[] = "./profiles";
+    $profiles_subdirs['required'][] = "./profiles";
   }
 
-  foreach($profiles_subdirs as $profiles_subdir) {
-    if (!$dir = opendir($profiles_subdir)) {
-      drush_log(dt("Cannot find profiles directory"), 'error');
-      return FALSE;
-    }
-
-    while (FALSE !== ($name = readdir($dir))) {
-      $languages = array();
-      if (($name == '..') || ($name == '.') || (!is_dir("$profiles_subdir/$name"))) {
+  foreach($profiles_subdirs as $profiles_dir_type => $profiles_subdir_list) {
+    foreach ($profiles_subdir_list as $profiles_subdir) {
+      // Required directories.
+      if ($profiles_dir_type == 'required' && !opendir($profiles_subdir)) {
+        drush_log(dt("Cannot open profiles directory: @dir", array('@dir' => $profiles_subdir)), 'error');
+        return FALSE;
+      }
+      // Optional directories.
+      elseif ($profiles_dir_type == 'optional' && !file_exists($profiles_subdir)) {
+        drush_log(dt("Cannot find optional profiles directory: @dir", array('@dir' => $profiles_subdir)));
         continue;
       }
 
-      $profile = new stdClass();
-      $profile->name = $name;
-      $profile->info = array();
+      $profiles_in_subdir = _provision_find_profiles_in_dir($profiles_subdir);
+      if ($profiles_in_subdir && !empty($profiles_in_subdir)) {
+        $profiles = array_merge($profiles, $profiles_in_subdir);
+      }
+    }
+  }
+  return $profiles;
+}
 
-      if (drush_drupal_major_version() >= 8) {
-        $yaml_file = "$profiles_subdir/$name/$name.info.yml";
-        if(!file_exists($yaml_file)) {
-          drush_log(dt("@name.info.yml not found.", array("@name" => $name)), 'notice');
-          unset($files[$name]);
-          continue;
-        }
-        $profile->info = Symfony\Component\Yaml\Yaml::parse($yaml_file);
+/**
+ * Find available profiles on this dir.
+ */
+function _provision_find_profiles_in_dir($profiles_subdir) {
+  $profiles = array();
+  if (!$dir = opendir($profiles_subdir)) {
+    drush_log(dt("Cannot open profiles directory"), 'error');
+    return FALSE;
+  }
 
-        // Skip hidden profiles.
-        if (isset($profile->info['hidden']) && $profile->info['hidden'] == 1) {
-          continue;
-        }
+  while (FALSE !== ($name = readdir($dir))) {
+    $languages = array();
+    if (($name == '..') || ($name == '.') || (!is_dir("$profiles_subdir/$name"))) {
+      continue;
+    }
 
-        if (!empty($profile->info['name'])) {
-          $profile->name = $profile->info['name'];
-        }
-        $profile->filename = $yaml_file;
-      }
-      else {
-        $info_file = "$profiles_subdir/$name/$name.info";
-        if (file_exists($info_file)) {
-          $profile->info = provision_parse_info_file($info_file);
-          // Skip hidden profiles
-          if (isset($profile->info['hidden']) && $profile->info['hidden'] == 1) {
-            continue;
-          }
-        }
-        $profile->filename = $info_file;
-      }
+    $profile = new stdClass();
+    $profile->name = $name;
+    $profile->info = array();
 
-      // Include code from the profile.
-      if (file_exists($profile_file = "$profiles_subdir/$name/$name.profile")) {
-        require_once($profile_file);
+    if (drush_drupal_major_version() >= 8) {
+      $yaml_file = "$profiles_subdir/$name/$name.info.yml";
+      if (!file_exists($yaml_file)) {
+        drush_log(dt("@name.info.yml not found.", array("@name" => $name)), 'notice');
+        unset($files[$name]);
+        continue;
       }
+      $profile->info = Symfony\Component\Yaml\Yaml::parse($yaml_file);
 
-      $func = $profile->name . "_profile_details";
-      if (function_exists($func)) {
-        $profile->info = array_merge($profile->info, $func());
+      // Skip hidden profiles.
+      if (isset($profile->info['hidden']) && $profile->info['hidden'] == 1) {
+        continue;
       }
 
-      $languages['en'] = 1;
-      // Find languages available
-      $files = array_keys(drush_scan_directory($profiles_subdir . '/' . $name . '/translations', '/\.po$/', array('.', '..', 'CVS'), 0, FALSE, 'filepath'));
-      $files = array_merge($files, array_keys(drush_scan_directory($profiles_subdir . '/' . $name , '/\.po$/', array('.', '..', 'CVS'), 0, FALSE, 'filepath')));
-      if (is_array($files)) {
-        foreach ($files as $file) {
-          if (preg_match('!(/|\.)([^\./]+)\.po$!', $file, $langcode)) {
-            $languages[$langcode[2]] = 1; // use the language name as an index to weed out duplicates
-          }
+      if (!empty($profile->info['name'])) {
+        $profile->name = $profile->info['name'];
+      }
+      $profile->filename = $yaml_file;
+    }
+    else {
+      $info_file = "$profiles_subdir/$name/$name.info";
+      if (file_exists($info_file)) {
+        $profile->info = provision_parse_info_file($info_file);
+        // Skip hidden profiles
+        if (isset($profile->info['hidden']) && $profile->info['hidden'] == 1) {
+          continue;
         }
       }
-      $profile->info['languages'] = array_keys($languages);
-
-      // Drupal 7 renamed the default install profile to 'standard'
-      // Aegir now allows projects to specify an "old short name" to provide an upgrade path when projects get renamed.
-      if ($profile->name == 'standard') {
-        $profile->info['old_short_name'] = 'default';
+      $profile->filename = $info_file;
+    }
+
+    // Include code from the profile.
+    if (file_exists($profile_file = "$profiles_subdir/$name/$name.profile")) {
+      require_once($profile_file);
+    }
+
+    $func = $profile->name . "_profile_details";
+    if (function_exists($func)) {
+      $profile->info = array_merge($profile->info, $func());
+    }
+
+    $languages['en'] = 1;
+    // Find languages available
+    $files = array_keys(drush_scan_directory($profiles_subdir . '/' . $name . '/translations', '/\.po$/', array(
+      '.',
+      '..',
+      'CVS'
+    ), 0, FALSE, 'filepath'));
+    $files = array_merge($files, array_keys(drush_scan_directory($profiles_subdir . '/' . $name, '/\.po$/', array(
+      '.',
+      '..',
+      'CVS'
+    ), 0, FALSE, 'filepath')));
+    if (is_array($files)) {
+      foreach ($files as $file) {
+        if (preg_match('!(/|\.)([^\./]+)\.po$!', $file, $langcode)) {
+          $languages[$langcode[2]] = 1; // use the language name as an index to weed out duplicates
+        }
       }
+    }
+    $profile->info['languages'] = array_keys($languages);
 
-      $profiles[$name] = $profile;
-      drush_log(dt('Found install profile %name', array('%name' => $name)));
+    // Drupal 7 renamed the default install profile to 'standard'
+    // Aegir now allows projects to specify an "old short name" to provide an upgrade path when projects get renamed.
+    if ($profile->name == 'standard') {
+      $profile->info['old_short_name'] = 'default';
     }
+
+    $profiles[$name] = $profile;
+    drush_log(dt('Found install profile %name', array('%name' => $name)));
   }
+
   return $profiles;
 }
 
-- 
1.9.1

