diff options
author | Angie Byron <webchick@24967.no-reply.drupal.org> | 2009-08-13 03:03:04 +0000 |
---|---|---|
committer | Angie Byron <webchick@24967.no-reply.drupal.org> | 2009-08-13 03:03:04 +0000 |
commit | 49699d5be129c467323fd469573df3fbf6dbc98e (patch) | |
tree | 40f53edd3ea9b67b08de9ad2f9840cc13b14e983 /includes | |
parent | 5327ed26c23b1620037031389e81d1a6ddebc410 (diff) | |
download | brdo-49699d5be129c467323fd469573df3fbf6dbc98e.tar.gz brdo-49699d5be129c467323fd469573df3fbf6dbc98e.tar.bz2 |
#533586 by dww and chx: Refactor dependency checks into sharable helper functions.
Diffstat (limited to 'includes')
-rw-r--r-- | includes/common.inc | 80 | ||||
-rw-r--r-- | includes/module.inc | 45 |
2 files changed, 84 insertions, 41 deletions
diff --git a/includes/common.inc b/includes/common.inc index bd41d283c..df885d362 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -4917,3 +4917,83 @@ function _drupal_flush_css_js() { } variable_set('css_js_query_string', $new_character . substr($string_history, 0, 19)); } + +/** + * Parse a dependency for comparison by drupal_check_incompatibility(). + * + * @param $dependency + * A dependency string, for example 'foo (>=7.x-4.5-beta5, 3.x)'. + * @return + * An associative array with three keys: + * - 'name' includes the name of the thing to depend on (e.g. 'foo'). + * - 'original_version' contains the original version string (which can be + * used in the UI for reporting incompatibilities). + * - 'versions' is a list of associative arrays, each containing the keys + * 'op' and 'version'. 'op' can be one of: '=', '==', '!=', '<>', '<', + * '<=', '>', or '>='. 'version' is one piece like '4.5-beta3'. + * Callers should pass this structure to drupal_check_incompatibility(). + * + * @see drupal_check_incompatibility() + */ +function drupal_parse_dependency($dependency) { + // We use named subpatterns and support every op that version_compare + // supports. Also, op is optional and defaults to equals. + $p_op = '(?P<operation>!=|==|=|<|<=|>|>=|<>)?'; + // Core version is always optional: 7.x-2.x and 2.x is treated the same. + $p_core = '(?:' . preg_quote(DRUPAL_CORE_COMPATIBILITY) . '-)?'; + $p_major = '(?P<major>\d+)'; + // By setting the minor version to x, branches can be matched. + $p_minor = '(?P<minor>(?:\d+|x)(?:-[A-Za-z]+\d+)?)'; + $value = array(); + $parts = explode('(', $dependency, 2); + $value['name'] = trim($parts[0]); + if (isset($parts[1])) { + $value['original_version'] = ' (' . $parts[1]; + foreach (explode(',', $parts[1]) as $version) { + if (preg_match("/^\s*$p_op\s*$p_core$p_major\.$p_minor/", $version, $matches)) { + $op = !empty($matches['operation']) ? $matches['operation'] : '='; + if ($matches['minor'] == 'x') { + // Drupal considers "2.x" to mean any version that begins with + // "2" (e.g. 2.0, 2.9 are all "2.x"). PHP's version_compare(), + // on the other hand, treats "x" as a string; so to + // version_compare(), "2.x" is considered less than 2.0. This + // means that >=2.x and <2.x are handled by version_compare() + // as we need, but > and <= are not. + if ($op == '>' || $op == '<=') { + $matches['major']++; + } + // Equivalence can be checked by adding two restrictions. + if ($op == '=' || $op == '==') { + $value['versions'][] = array('op' => '<', 'version' => ($matches['major'] + 1) . '.x'); + $op = '>='; + } + } + $value['versions'][] = array('op' => $op, 'version' => $matches['major'] . '.' . $matches['minor']); + } + } + } + return $value; +} + +/** + * Check whether a version is compatible with a given dependency. + * + * @param $v + * The parsed dependency structure from drupal_parse_dependency(). + * @param $current_version + * The version to check against (like 4.2). + * @return + * NULL if compatible, otherwise the original dependency version string that + * caused the incompatiblity. + * + * @see drupal_parse_dependency() + */ +function drupal_check_incompatibility($v, $current_version) { + if (!empty($v['versions'])) { + foreach ($v['versions'] as $required_version) { + if ((isset($required_version['op']) && !version_compare($current_version, $required_version['version'], $required_version['op']))) { + return $v['original_version']; + } + } + } +} diff --git a/includes/module.inc b/includes/module.inc index 3e8d5339b..6cd246d7b 100644 --- a/includes/module.inc +++ b/includes/module.inc @@ -95,50 +95,13 @@ function module_list($refresh = FALSE, $sort = FALSE, $fixed_list = NULL) { function _module_build_dependencies($files) { require_once DRUPAL_ROOT . '/includes/graph.inc'; $roots = $files; - // We use named subpatterns and support every op that version_compare - // supports. Also, op is optional and defaults to equals. - $p_op = '(?P<operation>!=|==|=|<|<=|>|>=|<>)?'; - // Core version is always optional: 7.x-2.x and 2.x is treated the same. - $p_core = '(?:' . preg_quote(DRUPAL_CORE_COMPATIBILITY) . '-)?'; - $p_major = '(?P<major>\d+)'; - // By setting the minor version to x, branches can be matched. - $p_minor = '(?P<minor>(?:\d+|x)(?:-[A-Za-z]+\d+)?)'; foreach ($files as $filename => $file) { $graph[$file->name]['edges'] = array(); if (isset($file->info['dependencies']) && is_array($file->info['dependencies'])) { - foreach ($file->info['dependencies'] as $dependency_name) { - $value = array(); - $parts = explode('(', $dependency_name, 2); - $dependency_name = trim($parts[0]); - if (isset($parts[1])) { - $value['original_version'] = ' (' . $parts[1]; - foreach (explode(',', $parts[1]) as $version) { - if (preg_match("/^\s*$p_op\s*$p_core$p_major\.$p_minor/", $version, $matches)) { - $op = !empty($matches['operation']) ? $matches['operation'] : '='; - if ($matches['minor'] == 'x') { - // Drupal considers "2.x" to mean any version that begins with - // "2" (e.g. 2.0, 2.9 are all "2.x"). PHP's version_compare(), - // on the other hand, treats "x" as a string; so to - // version_compare(), "2.x" is considered less than 2.0. This - // means that >=2.x and <2.x are handled by version_compare() - // as we need, but > and <= are not. - if ($op == '>' || $op == '<=') { - $matches['major']++; - } - // Equivalence is checked by preg. - if ($op == '=' || $op == '==') { - $value['versions'][] = array('preg' => '/^' . $matches['major'] . '\./'); - $op = ''; - } - } - if ($op) { - $value['versions'][] = array('op' => $op, 'version' => $matches['major'] . '.' . $matches['minor']); - } - } - } - } - $graph[$file->name]['edges'][$dependency_name] = $value; - unset($roots[$dependency_name]); + foreach ($file->info['dependencies'] as $dependency) { + $dependency_data = drupal_parse_dependency($dependency); + $graph[$file->name]['edges'][$dependency_data['name']] = $dependency_data; + unset($roots[$dependency_data['name']]); } } } |