diff -u b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php --- b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php +++ b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php @@ -28,4 +28,27 @@ /** + * Determines if a version satisfies the given constraints. + * + * This method uses \Composer\Semver\Semver::satisfies() but returns FALSE if + * the version or constraints are not valid instead of throwing an exception. + * + * @param string $version + * The version. + * @param string $constraints + * The constraints. + * + * @return bool + * TRUE if the version satisfies the constraints, otherwise FALSE. + */ + protected static function satisfies($version, $constraints) { + try { + return Semver::satisfies($version, $constraints); + } + catch (\UnexpectedValueException $exception) { + return FALSE; + } + } + + /** * {@inheritdoc} */ @@ -49,12 +72,26 @@ // https://www.drupal.org/node/3070401. throw new InfoParserException("The 'core_version_requirement' key is not supported in profiles in $filename"); } + if (!isset($parsed_info['core']) && !isset($parsed_info['core_version_requirement'])) { - throw new InfoParserException("The 'core' or the 'core_version_requirement' key must be present in " . $filename); + if (isset($parsed_info['dependencies'])) { + throw new InfoParserException("If the 'dependencies' key is used the 'core' or 'core_version_requirement' key is required in $filename"); + } + $composer_filename = dirname($filename) . '/composer.json'; + if (!file_exists($composer_filename)) { + throw new InfoParserException("If the 'core' or 'core_version_requirement' key is not provided a composer.json file is required in $filename"); + } + $parsed_info += $this->parseComposerFile($composer_filename); + if (static::isConstraintSatisfiedByPreviousVersion($parsed_info['core_version_requirement'], static::FIRST_COMPOSER_JSON_SUPPORTED_VERSION)) { + throw new InfoParserException('Core versions before ' . static::FIRST_COMPOSER_JSON_SUPPORTED_VERSION . "must be specified in the module info.yml in $filename"); + } } - if (isset($parsed_info['core']) && !preg_match("/^\d\.x$/", $parsed_info['core'])) { - throw new InfoParserException("Invalid 'core' value \"{$parsed_info['core']}\" in " . $filename); + else { + if (isset($parsed_info['core']) && !preg_match("/^\d\.x$/", $parsed_info['core'])) { + throw new InfoParserException("Invalid 'core' value \"{$parsed_info['core']}\" in " . $filename); + } } + if (isset($parsed_info['core_version_requirement'])) { $supports_pre_core_version_requirement_version = static::isConstraintSatisfiedByPreviousVersion($parsed_info['core_version_requirement'], static::FIRST_CORE_VERSION_REQUIREMENT_SUPPORTED_VERSION); // If the 'core_version_requirement' constraint does not satisfy any @@ -72,26 +109,12 @@ // https://www.drupal.org/node/3070401. throw new InfoParserException("The 'core_version_requirement' key is not supported in profiles in $filename"); } - if (!isset($parsed_info['core']) && !isset($parsed_info['core_version_requirement'])) { - if (isset($parsed_info['dependencies'])) { - throw new InfoParserException("If the 'dependencies' key is used the 'core' or 'core_version_requirement' key is required in $filename"); - } - $composer_filename = dirname($filename) . '/composer.json'; - if (!file_exists($composer_filename)) { - throw new InfoParserException("If the 'core' or 'core_version_requirement' key is not provided a composer.json file is required in $filename"); - } - $parsed_info += $this->parseComposerFile($composer_filename); - if (static::isConstraintSatisfiedByPreviousVersion($parsed_info['core_version_requirement'], static::FIRST_COMPOSER_JSON_SUPPORTED_VERSION)) { - throw new InfoParserException('Core versions before ' . static::FIRST_COMPOSER_JSON_SUPPORTED_VERSION . "must be specified in the module info.yml in $filename"); - } + throw new InfoParserException("The 'core' or the 'core_version_requirement' key must be present in " . $filename); } - else { - if (isset($parsed_info['core']) && !preg_match("/^\d\.x$/", $parsed_info['core'])) { - throw new InfoParserException("Invalid 'core' value \"{$parsed_info['core']}\" in " . $filename); - } + if (isset($parsed_info['core']) && !preg_match("/^\d\.x$/", $parsed_info['core'])) { + throw new InfoParserException("Invalid 'core' value \"{$parsed_info['core']}\" in " . $filename); } - if (isset($parsed_info['core_version_requirement'])) { $supports_pre_core_version_requirement_version = static::isConstraintSatisfiedByPreviousVersion($parsed_info['core_version_requirement'], static::FIRST_CORE_VERSION_REQUIREMENT_SUPPORTED_VERSION); // If the 'core_version_requirement' constraint does not satisfy any interdiff impossible; taking evasive action reverted: --- b/core/lib/Drupal/Core/Extension/ModuleExtensionList.php +++ a/core/lib/Drupal/Core/Extension/ModuleExtensionList.php @@ -219,20 +219,8 @@ */ protected function ensureRequiredDependencies(Extension $module, array $modules = []) { if (!empty($module->info['required'])) { + foreach ($module->info['dependencies'] as $dependency) { + $dependency_name = Dependency::createFromString($dependency)->getName(); - // Modern composer.json file. - if (!empty($module->info[InfoParserDynamic::COMPOSER_DEPENDENCIES])) { - $dependencies = array_keys($module->info[InfoParserDynamic::COMPOSER_DEPENDENCIES]); - } - else { - // Legacy .info.yml files. - $dependencies = array_map(function ($dependency) { - return Dependency::createFromString($dependency)->getName(); - }, $module->info['dependencies']); - } - foreach ($dependencies as $dependency_name) { - if ($dependency_name === 'core') { - continue; - } if (!isset($modules[$dependency_name]->info['required'])) { $modules[$dependency_name]->info['required'] = TRUE; $modules[$dependency_name]->info['explanation'] = $this->t('Dependency of required module @module', ['@module' => $module->info['name']]); unchanged: --- a/core/lib/Drupal/Core/Extension/ModuleExtensionList.php +++ b/core/lib/Drupal/Core/Extension/ModuleExtensionList.php @@ -209,8 +209,20 @@ protected function getInstalledExtensionNames() { */ protected function ensureRequiredDependencies(Extension $module, array $modules = []) { if (!empty($module->info['required'])) { - foreach ($module->info['dependencies'] as $dependency) { - $dependency_name = Dependency::createFromString($dependency)->getName(); + // Modern composer.json file. + if (!empty($module->info[InfoParserDynamic::COMPOSER_DEPENDENCIES])) { + $dependencies = array_keys($module->info[InfoParserDynamic::COMPOSER_DEPENDENCIES]); + } + else { + // Legacy .info.yml files. + $dependencies = array_map(function ($dependency) { + return Dependency::createFromString($dependency)->getName(); + }, $module->info['dependencies']); + } + foreach ($dependencies as $dependency_name) { + if ($dependency_name === 'core') { + continue; + } if (!isset($modules[$dependency_name]->info['required'])) { $modules[$dependency_name]->info['required'] = TRUE; $modules[$dependency_name]->info['explanation'] = $this->t('Dependency of required module @module', ['@module' => $module->info['name']]);