diff -u b/core/includes/install.core.inc b/core/includes/install.core.inc --- b/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -1197,6 +1197,8 @@ * - For non-interactive installations via install_drupal() settings. * - A discovered profile that is a distribution. If multiple profiles are * distributions, then the first discovered profile will be selected. + * If an inherited profile is detected that is a distribution, it will be + * chosen over its base profile. * - Only one visible profile is available. * * @param array $install_state @@ -1219,11 +1221,8 @@ } } // Check for a distribution profile. - foreach ($install_state['profiles'] as $profile) { - $profile_info = install_profile_info($profile->getName()); - if (!empty($profile_info['distribution'])) { - return $profile->getName(); - } + if ($distribution = \Drupal::service('profile_handler')->selectDistribution($install_state['profiles'])) { + return $distribution->getName(); } // Get all visible (not hidden) profiles. diff -u b/core/lib/Drupal/Core/Extension/ProfileHandler.php b/core/lib/Drupal/Core/Extension/ProfileHandler.php --- b/core/lib/Drupal/Core/Extension/ProfileHandler.php +++ b/core/lib/Drupal/Core/Extension/ProfileHandler.php @@ -167,19 +167,27 @@ // otherwise in the .info.yml file. $info['hidden'] = isset($info['hidden']) ? $info['hidden'] : TRUE; - // Add a default distribution name if the profile did not provide one. - // @see install_profile_info() - // @see drupal_install_profile_distribution_name() - if (!isset($info['distribution']['name'])) { - $info['distribution']['name'] = 'Drupal'; - } - $this->info_cache[$profile] = $info; } return $this->info_cache[$profile]; } /** + * {@inheritdoc} + */ + public function setProfileInfo($profile, $info) { + $this->info_cache[$profile] = $info; + // Also unset the cached profile extension so the updated info will + // be picked up. + unset($this->cache[$profile]); + } + + public function clearProfileCache() { + $this->cache = array(); + $this->info_cache = array(); + } + + /** * Create an Extension object for a profile. * * @param string $profile @@ -255,6 +263,30 @@ /** * {@inheritdoc} */ + public function selectDistribution($profile_list) { + // First, find all profiles marked as distributions + $distributions = array(); + foreach ($profile_list as $profile) { + $profile_name = is_object($profile) ? $profile->getName() : $profile; + $profile_info = $this->getProfileInfo($profile_name); + if (!empty($profile_info['distribution'])) { + $distributions[$profile_name] = $profile; + } + } + // Remove any base profiles. + foreach ($profile_list as $profile) { + $profile_name = is_object($profile) ? $profile->getName() : $profile; + $profile_info = $this->getProfileInfo($profile_name); + if ($base_profile = self::getProfileBaseName($profile_info)) { + unset($distributions[$base_profile]); + } + } + return !empty($distributions) ? current($distributions) : NULL; + } + + /** + * {@inheritdoc} + */ static public function getProfileBaseName($info) { return !empty($info['base profile']['name']) ? $info['base profile']['name'] diff -u b/core/lib/Drupal/Core/Extension/ProfileHandlerInterface.php b/core/lib/Drupal/Core/Extension/ProfileHandlerInterface.php --- b/core/lib/Drupal/Core/Extension/ProfileHandlerInterface.php +++ b/core/lib/Drupal/Core/Extension/ProfileHandlerInterface.php @@ -27,6 +27,24 @@ public function getProfileInfo($profile); /** + * Stores info data for a profile. + * + * This can be used in situations where the info cache needs to be changed + * This is used for testing. + * + * @param string $profile + * Name of profile. + * @param array $info + * The info array to be set. + */ + public function setProfileInfo($profile, $info); + + /** + * Clears the profile cache. + */ + public function clearProfileCache(); + + /** * Returns a list of dependent installation profiles. * * @param string $profile @@ -40,6 +58,22 @@ public function getProfiles($profile = NULL); /** + * Select the install distribution from the list of profiles. + * + * If there are multiple profiles marked as distributions, select the first. + * If there is an inherited profile marked as a distribution, select it over + * its base profile. + * + * @param array $profile_list + * List of profiles to search. Can be either an array of extensions or + * an array of profile name strings. + * @return \Drupal\Core\Extension\Extension or string + * The selected distribution, or NULL if none is found. The type returned + * is the same as the type passed in $profile_list. + */ + public function selectDistribution($profile_list); + + /** * Return the name of a profile from its info. * * The info array can reference a "base profile" in two ways: diff -u b/core/modules/system/system.module b/core/modules/system/system.module --- b/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -1012,6 +1012,12 @@ if ($profile && isset($modules[$profile])) { // The installation profile is required, if it's a valid module. $modules[$profile]->info['required'] = TRUE; + // Add a default distribution name if the profile did not provide one. + // @see install_profile_info() + // @see drupal_install_profile_distribution_name() + if (!isset($modules[$profile]->info['distribution']['name'])) { + $modules[$profile]->info['distribution']['name'] = 'Drupal'; + } } return $modules; diff -u b/core/tests/Drupal/KernelTests/Core/Extension/ProfileHandlerTest.php b/core/tests/Drupal/KernelTests/Core/Extension/ProfileHandlerTest.php --- b/core/tests/Drupal/KernelTests/Core/Extension/ProfileHandlerTest.php +++ b/core/tests/Drupal/KernelTests/Core/Extension/ProfileHandlerTest.php @@ -41,8 +41,10 @@ $this->assertNotEmpty($info['profile_list']); $profile_list = $info['profile_list']; // Testing order of profile list. - $this->assertEquals($profile_list, array('minimal' => 'minimal', 'testing_inherited' => 'testing_inherited')); - $this->assertEquals($info['distribution']['name'], 'Drupal', 'Check default distribution name'); + $this->assertEquals($profile_list, array( + 'minimal' => 'minimal', + 'testing_inherited' => 'testing_inherited' + )); } /** @@ -70,2 +72,33 @@ + /** + * Tests getting profile dependency list. + * + * @covers ::selectDistribution + * @covers ::setProfileInfo + */ + public function testSelectDistribution() { + $profile_handler = $this->container->get('profile_handler'); + $profiles = array('minimal', 'testing_inherited'); + $base_info = $profile_handler->getProfileInfo('minimal'); + $profile_info = $profile_handler->getProfileInfo('testing_inherited'); + + // Neither profile has distribution set + $distribution = $profile_handler->selectDistribution($profiles); + $this->assertEmpty($distribution, 'No distribution should be selected'); + + // Set base profile distribution + $base_info['distribution']['name'] = 'Minimal'; + $profile_handler->setProfileInfo('minimal', $base_info); + // Base profile distribution should not be selected + $distribution = $profile_handler->selectDistribution($profiles); + $this->assertEmpty($distribution, 'Base profile distribution should not be selected'); + + // Set main profile distribution + $profile_info['distribution']['name'] = 'Testing Inherited'; + $profile_handler->setProfileInfo('testing_inherited', $profile_info); + // Main profile distribution should be selected + $distribution = $profile_handler->selectDistribution($profiles); + $this->assertEquals($distribution, 'testing_inherited'); + } + } only in patch2: unchanged: --- /dev/null +++ b/core/profiles/testing_inherited/src/Tests/InheritedProfileTest.php @@ -0,0 +1,29 @@ +drupalGet(''); + // Check the login block is present. + $this->assertLink(t('Create new account')); + $this->assertResponse(200); + // Check that proper modules were enabled or not. + $this->assertTrue(\Drupal::moduleHandler()->moduleExists('config')); + $this->assertFalse(\Drupal::moduleHandler()->moduleExists('dblog')); + } + +}