Index: release/views/project_release.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project/release/views/project_release.views.inc,v
retrieving revision 1.4
diff -u -r1.4 project_release.views.inc
--- release/views/project_release.views.inc	8 Aug 2009 01:24:02 -0000	1.4
+++ release/views/project_release.views.inc	30 Oct 2009 20:13:17 -0000
@@ -20,6 +20,13 @@
   // have a group defined will go into this field by default.
   $data['project_release_nodes']['table']['group']  = t('Project release');
 
+  $data['project_release_nodes']['table']['base'] = array(
+    'field' => 'nid',
+    'title' => t('Project release'),
+    'help' => t('Project release information.'),
+    'weight' => -10,
+  );
+
   $data['project_release_nodes']['table']['join'] = array(
     'node' => array(
       'left_field' => 'nid',
Index: release/package-release-nodes.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project/release/package-release-nodes.php,v
retrieving revision 1.50
diff -u -r1.50 package-release-nodes.php
--- release/package-release-nodes.php	18 Aug 2009 21:18:30 -0000	1.50
+++ release/package-release-nodes.php	30 Oct 2009 20:13:17 -0000
@@ -1,4 +1,3 @@
-#!/usr/bin/php
 <?php
 
 // $Id: package-release-nodes.php,v 1.50 2009/08/18 21:18:30 dww Exp $
@@ -22,29 +21,29 @@
 // The root of your Drupal installation, so we can properly bootstrap
 // Drupal. This should be the full path to the directory that holds
 // your index.php file, the "includes" subdirectory, etc.
-$drupal_root = '';
+$drupal_root = '/home/boombatower/software/drupal-6';
 
 // The name of your site. Required so that when we bootstrap Drupal in
 // this script, we find the right settings.php file in your sites folder.
 // For example, on drupal.org:
 // $site_name = 'drupal.org';
-$site_name = '';
+$site_name = 'pift.d6x.loc';
 
 // The CVSROOT for the repository this script will be packaging
 // releases from.  For example, on drupal.org:
 // $cvs_root = ':pserver:anonymous@cvs.drupal.org:/cvs/drupal';
-$cvs_root = '';
+$cvs_root = ':pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal-contrib';
 
 // Root of the temporary directory where you want packages to be
 // made. Subdirectories will be created depending on the task.
-$tmp_root = '';
+$tmp_root = '/home/boombatower/download/build';
 
 // Location of the LICENSE.txt file you want included in all packages.
-$license = '';
+$license = '/home/boombatower/software/simpletest/CHANGELOG.txt';
 
 // Location of the INSTALL.txt file you want included in all
 // translation packages.
-$trans_install = '';
+$trans_install = '/home/boombatower/software/simpletest/CHANGELOG.txt';
 
 
 // ------------------------------------------------------------
@@ -58,7 +57,7 @@
 // "files/projects" directory of your root Drupal installation. If
 // that's not the case, you should customize these.
 $dest_root = $drupal_root;
-$dest_rel = 'files/projects';
+$dest_rel = 'sites/pift.d6x.loc/files/projects';
 
 // --------------
 // External tools
@@ -305,9 +304,9 @@
       }
     }
     if (!empty($fails)) {
-      wd_msg('ERROR: Failed to re-generate release history XML files for !num project(s)', array('!num' => $fails)); 
+      wd_msg('ERROR: Failed to re-generate release history XML files for !num project(s)', array('!num' => $fails));
     }
-    wd_msg('Done re-generating release history XML files for !num project(s)', array('!num' => $i)); 
+    wd_msg('Done re-generating release history XML files for !num project(s)', array('!num' => $i));
   }
 }
 
@@ -370,6 +369,12 @@
   global $cvs, $tar, $gzip, $rm, $ln;
   global $license, $trans_install;
 
+  // If project_info module exists then load package.inc.
+  static $project_info;
+  if (!isset($project_info) && ($project_info = module_exists('project_info'))) {
+    module_load_include('package.inc', 'project_info');
+  }
+
   $rid = 2;
   // Files to ignore when checking timestamps:
   $exclude = array('.', '..', 'LICENSE.txt');
@@ -417,7 +422,7 @@
     return false;
   }
 
-  // Fix any .info files
+  // Fix any .info files.
   foreach ($info_files as $file) {
     if (!fix_info_file_version($file, $uri, $version)) {
       wd_err("ERROR: Failed to update version in %file, aborting packaging", array('%file' => $file), $view_link);
@@ -425,6 +430,11 @@
     }
   }
 
+  // Allow project_info to process the module .info file.
+  if ($project_info) {
+    project_info_package_info_process_all($nid, $info_files, $uri, $version);
+  }
+
   // Link not copy, since we want to preserve the date...
   if (!drupal_exec("$ln -sf $license $uri/LICENSE.txt")) {
     return false;
@@ -569,7 +579,7 @@
           wd_err("ERROR: Unable to filter fuzzy strings and copying the translation files in %uri translation in version %version, not packaging", array('%uri' => $uri, '%version' => $version), $view_link);
           return FALSE;
         }
-      
+
         // Add file to package.
         $to_tar .= ' '. $target;
       }
Index: info/project_info.info
===================================================================
RCS file: info/project_info.info
diff -N info/project_info.info
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ info/project_info.info	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,6 @@
+; $Id$
+name = Project info
+description = Provides information related to projects, such as dependencies.
+package = Project
+dependencies[] = project_release
+core = 6.x
Index: info/views/project_info.views.inc
===================================================================
RCS file: info/views/project_info.views.inc
diff -N info/views/project_info.views.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ info/views/project_info.views.inc	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,140 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Provide views data definition.
+ */
+
+/**
+ * Implementation of hook_views_data()
+ */
+function project_info_views_data() {
+  $data = array();
+
+  // ----------------------------------------------------------------
+  // project_info_module table -- basic table information.
+
+  $data['project_info_module']['table']['group']  = t('Project info module');
+
+  $data['project_info_module']['table']['base'] = array(
+    'field' => 'module_id',
+    'title' => t('Project info module'),
+    'help' => t('The modules contained by a project release.'),
+    'weight' => -10,
+  );
+
+  $data['project_info_module']['table']['join'] = array(
+    'project_release_nodes' => array(
+      'left_field' => 'nid',
+      'field' => 'rid',
+    ),
+    'node' => array(
+      'left_field' => 'nid',
+      'field' => 'rid',
+    ),
+  );
+
+  $data['project_info_module']['module_id'] = array(
+    'title' => t('Module ID'),
+    'help' => t('Unique module ID.'),
+    'field' => array(
+      'handler' => 'views_handler_field_numeric',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_numeric',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+  );
+
+  $data['project_info_module']['rid'] = array(
+    'title' => t('Release ID'),
+    'help' => t('The {node}.nid of the project_release node.'),
+    'relationship' => array(
+      'help' => t('Add a relationship to gain access to more node data for releases.'),
+      'base' => 'project_release_nodes',
+      'handler' => 'views_handler_relationship',
+      'label' => t('Release node'),
+    ),
+  );
+
+  $data['project_info_module']['name'] = array(
+    'title' => t('Module name'),
+    'help' => t('Name of a module contained by the release.'),
+    'field' => array(
+      'handler' => 'views_handler_field',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+  );
+
+
+  // ----------------------------------------------------------------
+  // project_info_dependency table -- basic table information.
+
+  $data['project_info_dependency']['table']['group']  = t('Project info dependency');
+
+  $data['project_info_dependency']['table']['base'] = array(
+    'field' => 'dependency_id',
+    'title' => t('Project info dependency'),
+    'help' => t('The dependencies of each project release.'),
+    'weight' => -9,
+  );
+
+  $data['project_info_dependency']['table']['join'] = array(
+    'project_release_nodes' => array(
+      'left_field' => 'nid',
+      'field' => 'rid',
+    ),
+    'node' => array(
+      'left_field' => 'nid',
+      'field' => 'rid',
+    ),
+  );
+
+  $data['project_info_dependency']['dependency_id'] = array(
+    'title' => t('Dependency ID'),
+    'help' => t('Unique dependency ID.'),
+    'field' => array(
+      'handler' => 'views_handler_field_numeric',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_numeric',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+  );
+
+  $data['project_info_dependency']['rid'] = array(
+    'title' => t('Release ID'),
+    'help' => t('The {node}.nid of the project_release node.'),
+    'relationship' => array(
+      'help' => t('Add a relationship to gain access to more node data for releases.'),
+      'base' => 'project_release_nodes',
+      'handler' => 'views_handler_relationship',
+      'label' => t('Release node'),
+    ),
+  );
+
+  $data['project_info_dependency']['module_id'] = array(
+    'title' => t('Dependency module'),
+    'help' => t('Reference to module that the release is dependent on.'),
+    'relationship' => array(
+      'help' => t('Add a relationship to gain access to more node data for releases.'),
+      'base' => 'project_info_module',
+      'handler' => 'views_handler_relationship',
+      'label' => t('dependency -> module'),
+    ),
+  );
+
+  return $data;
+}
Index: info/project_info.install
===================================================================
RCS file: info/project_info.install
diff -N info/project_info.install
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ info/project_info.install	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,91 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Provides schema for storing project information.
+ */
+
+/**
+ * Implementation of hook_schema().
+ */
+function project_info_schema() {
+  $schema = array();
+
+  $schema['project_info_module'] = array(
+    'description' => 'The modules contained by a project release.',
+    'fields' => array(
+      'module_id' => array(
+        'description' => 'Unique module ID.',
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'rid' => array(
+        'description' => 'The {node}.nid of the project_release node.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'name' => array(
+        'description' => 'Name of a module contained by the release.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+    ),
+    'primary key' => array('module_id'),
+    'indexes' => array(
+      'rid' => array('rid'),
+    ),
+  );
+
+  $schema['project_info_dependency'] = array(
+    'description' => 'The dependencies of each project release.',
+    'fields' => array(
+      'dependency_id' => array(
+        'description' => 'Unique dependency ID.',
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'rid' => array(
+        'description' => 'The {node}.nid of the project_release node.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'module_id' => array(
+        'description' => 'Reference to module that the release is dependent on.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+    ),
+    'primary key' => array('dependency_id'),
+    'indexes' => array(
+      'rid' => array('rid'),
+      'module_id' => array('module_id'),
+    ),
+  );
+
+  return $schema;
+}
+
+/**
+ * Implementation of hook_install().
+ */
+function project_info_install() {
+  drupal_install_schema('project_info');
+}
+
+/**
+ * Implementation of hook_uninstall().
+ */
+function project_info_uninstall() {
+  drupal_uninstall_schema('project_info');
+}
Index: info/views/project_info.views_default.inc
===================================================================
RCS file: info/views/project_info.views_default.inc
diff -N info/views/project_info.views_default.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ info/views/project_info.views_default.inc	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,329 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Contains default views on behalf of the project_info module.
+ */
+
+/**
+ * Implementation of hook_default_view_views().
+ */
+function project_info_views_default_views() {
+  // ----------------------------------------------------------------
+  // project_info_module
+
+  $view = new view;
+  $view->name = 'project_info_module';
+  $view->description = 'The modules contained by a project release.';
+  $view->tag = 'project_info';
+  $view->view_php = '';
+  $view->base_table = 'project_info_module';
+  $view->is_cacheable = FALSE;
+  $view->api_version = 2;
+  $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
+  $handler = $view->new_display('default', 'Defaults', 'default');
+  $handler->override_option('relationships', array(
+    'rid' => array(
+      'label' => 'Release node',
+      'required' => 1,
+      'id' => 'rid',
+      'table' => 'project_info_module',
+      'field' => 'rid',
+      'relationship' => 'none',
+    ),
+  ));
+  $handler->override_option('fields', array(
+    'name' => array(
+      'label' => '',
+      'alter' => array(
+        'alter_text' => 0,
+        'text' => '',
+        'make_link' => 0,
+        'path' => '',
+        'link_class' => '',
+        'alt' => '',
+        'prefix' => '',
+        'suffix' => '',
+        'help' => '',
+        'trim' => 1,
+        'max_length' => '128',
+        'word_boundary' => 1,
+        'ellipsis' => 1,
+        'strip_tags' => 0,
+        'html' => 0,
+      ),
+      'exclude' => 0,
+      'id' => 'name',
+      'table' => 'project_info_module',
+      'field' => 'name',
+      'relationship' => 'none',
+    ),
+  ));
+  $handler->override_option('sorts', array(
+    'name' => array(
+      'order' => 'ASC',
+      'id' => 'name',
+      'table' => 'project_info_module',
+      'field' => 'name',
+      'relationship' => 'none',
+    ),
+  ));
+  $handler->override_option('arguments', array(
+    'pid' => array(
+      'default_action' => 'not found',
+      'style_plugin' => 'default_summary',
+      'style_options' => array(),
+      'wildcard' => 'all',
+      'wildcard_substitution' => 'All',
+      'title' => '',
+      'breadcrumb' => '',
+      'default_argument_type' => 'fixed',
+      'default_argument' => '',
+      'validate_type' => 'project_nid',
+      'validate_fail' => 'not found',
+      'break_phrase' => 0,
+      'not' => 0,
+      'id' => 'pid',
+      'table' => 'project_release_nodes',
+      'field' => 'pid',
+      'relationship' => 'rid',
+      'validate_user_argument_type' => 'uid',
+      'validate_user_roles' => array(
+        '2' => 0,
+      ),
+      'default_options_div_prefix' => '',
+      'default_argument_user' => 0,
+      'default_argument_fixed' => '',
+      'default_argument_php' => '',
+      'validate_argument_node_type' => array(
+        'project_project' => 0,
+        'project_release' => 0,
+        'project_issue' => 0,
+        'page' => 0,
+        'story' => 0,
+      ),
+      'validate_argument_node_access' => 0,
+      'validate_argument_nid_type' => 'nid',
+      'validate_argument_vocabulary' => array(
+        '1' => 0,
+        '2' => 0,
+        '3' => 0,
+      ),
+      'validate_argument_type' => 'tid',
+      'validate_argument_transform' => 0,
+      'validate_user_restrict_roles' => 0,
+      'validate_argument_project_term_vocabulary' => array(
+        '2' => 0,
+      ),
+      'validate_argument_project_term_argument_type' => 'tid',
+      'validate_argument_project_term_argument_action_top_without' => 'pass',
+      'validate_argument_project_term_argument_action_top_with' => 'pass',
+      'validate_argument_project_term_argument_action_child' => 'pass',
+      'validate_argument_php' => '',
+    ),
+  ));
+  $handler->override_option('access', array(
+    'type' => 'none',
+  ));
+  $handler->override_option('cache', array(
+    'type' => 'none',
+  ));
+  $handler->override_option('empty', '<em>The project does not contain any modules.</em>');
+  $handler->override_option('empty_format', '1');
+  $handler->override_option('use_pager', 'mini');
+  $handler->override_option('style_plugin', 'list');
+  $handler->override_option('style_options', array(
+    'grouping' => '',
+    'type' => 'ul',
+  ));
+
+  $views[$view->name] = $view;
+
+
+  // ----------------------------------------------------------------
+  // project_info_module
+
+  $view = new view;
+  $view->name = 'project_info_dependency';
+  $view->description = 'The dependencies of a project release.';
+  $view->tag = 'project_info';
+  $view->view_php = '';
+  $view->base_table = 'project_info_dependency';
+  $view->is_cacheable = FALSE;
+  $view->api_version = 2;
+  $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
+  $handler = $view->new_display('default', 'Defaults', 'default');
+  $handler->override_option('relationships', array(
+    'rid' => array(
+      'label' => 'release -> dependency',
+      'required' => 1,
+      'id' => 'rid',
+      'table' => 'project_info_dependency',
+      'field' => 'rid',
+      'relationship' => 'none',
+    ),
+    'module_id' => array(
+      'label' => 'dependency -> module',
+      'required' => 1,
+      'id' => 'module_id',
+      'table' => 'project_info_dependency',
+      'field' => 'module_id',
+      'relationship' => 'none',
+    ),
+    'rid_1' => array(
+      'label' => 'dependency -> module -> release',
+      'required' => 1,
+      'id' => 'rid_1',
+      'table' => 'project_info_module',
+      'field' => 'rid',
+      'relationship' => 'module_id',
+    ),
+    'pid' => array(
+      'label' => 'dependency -> module -> release -> project',
+      'required' => 1,
+      'id' => 'pid',
+      'table' => 'project_release_nodes',
+      'field' => 'pid',
+      'relationship' => 'rid_1',
+    ),
+  ));
+  $handler->override_option('fields', array(
+    'uri' => array(
+      'label' => '',
+      'alter' => array(
+        'alter_text' => 0,
+        'text' => '',
+        'make_link' => 1,
+        'path' => 'project/[uri]',
+        'link_class' => '',
+        'alt' => '',
+        'prefix' => '',
+        'suffix' => '',
+        'help' => '',
+        'trim' => 0,
+        'max_length' => '',
+        'word_boundary' => 1,
+        'ellipsis' => 1,
+        'strip_tags' => 0,
+        'html' => 0,
+      ),
+      'link_to_node' => 0,
+      'exclude' => 1,
+      'id' => 'uri',
+      'table' => 'project_projects',
+      'field' => 'uri',
+      'relationship' => 'pid',
+    ),
+    'name' => array(
+      'label' => '',
+      'alter' => array(
+        'alter_text' => 0,
+        'text' => '',
+        'make_link' => 0,
+        'path' => '',
+        'link_class' => '',
+        'alt' => '',
+        'prefix' => '',
+        'suffix' => '',
+        'help' => '',
+        'trim' => 0,
+        'max_length' => '',
+        'word_boundary' => 1,
+        'ellipsis' => 1,
+        'strip_tags' => 0,
+        'html' => 0,
+      ),
+      'exclude' => 0,
+      'id' => 'name',
+      'table' => 'project_info_module',
+      'field' => 'name',
+      'relationship' => 'module_id',
+    ),
+  ));
+  $handler->override_option('sorts', array(
+    'uri' => array(
+      'order' => 'ASC',
+      'id' => 'uri',
+      'table' => 'project_projects',
+      'field' => 'uri',
+      'relationship' => 'pid',
+    ),
+  ));
+  $handler->override_option('arguments', array(
+    'pid' => array(
+      'default_action' => 'not found',
+      'style_plugin' => 'default_summary',
+      'style_options' => array(),
+      'wildcard' => 'all',
+      'wildcard_substitution' => 'All',
+      'title' => '',
+      'breadcrumb' => '',
+      'default_argument_type' => 'fixed',
+      'default_argument' => '',
+      'validate_type' => 'project_nid',
+      'validate_fail' => 'not found',
+      'break_phrase' => 0,
+      'not' => 0,
+      'id' => 'pid',
+      'table' => 'project_release_nodes',
+      'field' => 'pid',
+      'relationship' => 'rid',
+      'validate_user_argument_type' => 'uid',
+      'validate_user_roles' => array(
+        '2' => 0,
+      ),
+      'default_options_div_prefix' => '',
+      'default_argument_user' => 0,
+      'default_argument_fixed' => '',
+      'default_argument_php' => '',
+      'validate_argument_node_type' => array(
+        'project_project' => 0,
+        'project_release' => 0,
+        'project_issue' => 0,
+        'page' => 0,
+        'story' => 0,
+      ),
+      'validate_argument_node_access' => 0,
+      'validate_argument_nid_type' => 'nid',
+      'validate_argument_vocabulary' => array(
+        '1' => 0,
+        '2' => 0,
+        '3' => 0,
+      ),
+      'validate_argument_type' => 'tid',
+      'validate_argument_transform' => 0,
+      'validate_user_restrict_roles' => 0,
+      'validate_argument_project_term_vocabulary' => array(
+        '2' => 0,
+      ),
+      'validate_argument_project_term_argument_type' => 'tid',
+      'validate_argument_project_term_argument_action_top_without' => 'pass',
+      'validate_argument_project_term_argument_action_top_with' => 'pass',
+      'validate_argument_project_term_argument_action_child' => 'pass',
+      'validate_argument_php' => '',
+    ),
+  ));
+  $handler->override_option('access', array(
+    'type' => 'none',
+  ));
+  $handler->override_option('cache', array(
+    'type' => 'none',
+  ));
+  $handler->override_option('empty', '<em>The project does not have any dependencies.</em>');
+  $handler->override_option('empty_format', '1');
+  $handler->override_option('use_pager', 'mini');
+  $handler->override_option('style_plugin', 'list');
+  $handler->override_option('style_options', array(
+    'grouping' => 'uri',
+    'type' => 'ul',
+  ));
+  $handler->override_option('row_options', array(
+    'inline' => array(),
+    'separator' => '',
+  ));
+
+  $views[$view->name] = $view;
+
+  return $views;
+}
Index: info/project_info.package.inc
===================================================================
RCS file: info/project_info.package.inc
diff -N info/project_info.package.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ info/project_info.package.inc	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,147 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Provides information related to projects, such as dependencies.
+ */
+
+/**
+ * Parse Drupal info files for project information.
+ *
+ * @param $rid
+ *   The project release ID.
+ * @param $info_files
+ *   List of .info files to be processed.
+ * @param $uri
+ *   The short name of the project.
+ * @param $version
+ *   The version of the release being processed.
+ */
+function project_info_package_info_process_all($rid, array $info_files, $uri, $version) {
+  // Only process .info files for 6.x API and above.
+  if (($major = array_shift(explode('.', $version, 2))) && $major >= 6) {
+    // Clear previous records for the release.
+    project_info_package_list_clear($rid);
+    project_info_package_dependency_clear($rid);
+
+    // Store list of modules.
+    project_info_package_list_store($rid, $info_files);
+  }
+}
+
+/**
+ * Clear the list of modules for a release.
+ *
+ * @param $rid
+ *   The project release ID.
+ */
+function project_info_package_list_clear($rid) {
+  db_query('DELETE FROM {project_info_module} WHERE rid = %d', $rid);
+}
+
+/**
+ * Store the list of modules for a release.
+ *
+ * @param $rid
+ *   The project release ID.
+ * @param $info_files
+ *   List of .info files to be processed.
+ */
+function project_info_package_list_store($rid, array $info_files) {
+  foreach ($info_files as $file) {
+    $module = basename($file, '.info');
+
+    $info = array(
+      'rid' => $rid,
+      'name' => $module,
+    );
+    drupal_write_record('project_info_module', $info);
+  }
+}
+
+/**
+ * Clear the list of dependencies for a release.
+ *
+ * @param $rid
+ *   The project release ID.
+ */
+function project_info_package_dependency_clear($rid) {
+  db_query('DELETE FROM {project_info_dependency} WHERE rid = %d', $rid);
+}
+
+/**
+ * Store the list of dependencies for a release.
+ *
+ * @param $rid
+ *   The project release ID.
+ * @param $info_files
+ *   List of .info files to be processed.
+ */
+function project_info_package_info_process($rid, array $info_files) {
+  foreach ($info_files as $file) {
+    $info = drupal_parse_info_file($file);
+
+    foreach ($info['dependencies'] as $dependency) {
+      if ($nid = project_get_nid_from_uri($dependency)) {
+        // Load the project and determine is core API version.
+        $project = node_load($nid);
+        list($api_version, $api_tid) = project_info_package_core_api($project);
+
+        // Cycle through the releases made by the project until a dev branch is
+        // found of the latest stable series that matches the core API.
+        $releases = project_release_get_releases($project, TRUE);
+        $best_release = NULL;
+        foreach ($releases as $release) {
+          list($api_version2, $api_tid2) = project_info_package_core_api($release);
+          if ($api_tid2 == $api_tid) {
+            if ($release->project_release['rebuild'] && $best_release &&
+              $release->project_release['version_major'] > $best_release->project_release['version_major']) {
+              $best_release = $release;
+            }
+          }
+        }
+
+        // Store the dependency if a best release was found.
+        if ($best_release) {
+          $result = db_query("SELECT module_id FROM {project_info_module}
+                              WHERE rid = %d
+                              AND name ='%s'", $best_release->nid, $dependency);
+          if ($module_id = db_result($result)) {
+            $info = array(
+              'rid' => $rid,
+              'module_id' => $module_id,
+            );
+            drupal_write_record('project_info_dependency', $info);
+          }
+        }
+      }
+    }
+  }
+}
+
+
+/**
+ * Attempt to determine the Drupal core API version.
+ *
+ * @param $node
+ *   Node object.
+ * @return
+ *   Core API version information in the format: array($api_version, $api_tid).
+ */
+function project_info_package_core_api($node) {
+  if (!empty($node->taxonomy)) {
+    // Relase API version vocabulary.
+    $api_vid = _project_release_get_api_vid();
+
+    foreach ($node->taxonomy as $tid => $term) {
+      if ($term->vid == $api_vid) {
+        $api_version = array_shift(explode('.', $term->name, 2));
+        $api_tid = $term->tid;
+
+        return array($api_version, $api_tid);
+      }
+    }
+  }
+  return array(NULL, NULL);
+}
Index: info/project_info.module
===================================================================
RCS file: info/project_info.module
diff -N info/project_info.module
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ info/project_info.module	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,103 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Provides information related to projects, such as dependencies.
+ */
+
+/**
+ * Implementation of hook_block().
+ */
+function project_info_block($op = 'list', $delta = 0, $edit = array()) {
+  if ($op == 'list') {
+    return array(
+      array('info' => t('Project info module list')),
+      array('info' => t('Project info dependency list')),
+    );
+  }
+  elseif ($op == 'view') {
+    if (arg(0) == 'node') {
+      switch ($delta) {
+        case 0:
+          return array(
+            'subject' => t('Modules'),
+            'content' => views_embed_view('project_info_module', 'default', arg(1)),
+          );
+        case 1:
+          return array(
+            'subject' => t('Dependencies'),
+            'content' => views_embed_view('project_info_dependency', 'default', arg(1)),
+          );
+      }
+    }
+  }
+}
+
+/**
+ * Implementation of hook_views_api().
+ */
+function project_info_views_api() {
+  return array(
+    'api' => 2,
+    'path' => drupal_get_path('module', 'project_info') . '/views',
+  );
+}
+
+/**
+ * Load the list of modules contained by a project release.
+ *
+ * @param $rid
+ *   Project release ID.
+ * @return
+ *   List of modules.
+ */
+function project_info_module_list_get($rid) {
+  $result = db_query('SELECT name FROM {project_info_module} WHERE rid = %d', $rid);
+  $modules = array();
+  while ($module = db_result($result)) {
+    $modules[] = $module;
+  }
+  return $modules;
+}
+
+/**
+ * Load a module.
+ *
+ * @param $module_id
+ *   Module ID to load.
+ * @return
+ *   Array of module information.
+ */
+function project_info_module_get($module_id) {
+  static $modules = array();
+
+  if (!isset($modules[$module_id])) {
+    $result = db_query('SELECT * FROM {project_info_module} WHERE module_id = %d', $module_id);
+    $modules[$module_id] = db_fetch_array($result);
+  }
+  return $modules[$module_id];
+}
+
+/**
+ * Recursively determine the list of dependencies of a release.
+ *
+ * @param $rid
+ *   Project release ID.
+ * @param $dependencies
+ *   (Optional) Array of already determined dependencies.
+ * @return
+ *   List of dependencies of the release.
+ */
+function project_info_dependency_list_get($rid, $dependencies = array()) {
+  $result = db_query('SELECT module_id FROM {project_info_dependency} WHERE rid = %d', $rid);
+  while ($module_id = db_result($result)) {
+    $module = project_info_module_get($module_id);
+
+    if (!in_array($module['rid'], $dependencies)) {
+      $dependencies[] = $module['rid'];
+      $dependencies = project_info_dependency_list_get($module['rid'], $dependencies);
+    }
+  }
+  return $dependencies;
+}
