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 11 Nov 2009 00:47:43 -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 11 Nov 2009 00:47:43 -0000
@@ -370,6 +370,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 +423,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 +431,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;
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 @@
+ '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,93 @@
+ '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 @@
+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', 'The project does not contain any modules.');
+ $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', 'The project does not have any dependencies.');
+ $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.legacy.inc
===================================================================
RCS file: info/project_info.legacy.inc
diff -N info/project_info.legacy.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ info/project_info.legacy.inc 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,275 @@
+ 'fieldset',
+ '#title' => t('Filter'),
+ );
+ $form['filter']['api'] = array(
+ '#type' => 'checkboxes',
+ '#title' => t('API'),
+ '#description' => t('Select the core API versions that releases must be compatible with.'),
+ '#options' => array(),
+ '#default_value' => array(),
+ );
+ $terms = project_release_get_api_taxonomy();
+ foreach ($terms as $term) {
+ $form['filter']['api']['#options'][$term->tid] = $term->name;
+
+ // Defaultly select
+ if (($major = array_shift(explode('.', $term->name, 2))) && $major >= PROJECT_INFO_MINIMUM_API) {
+ $form['filter']['api']['#default_value'][] = $term->tid;
+ }
+ }
+
+ $form['op'] = array(
+ '#type' => 'submit',
+ '#value' => t('Submit'),
+ );
+
+ return $form;
+}
+
+/**
+ * Ensure that the directory constant has been set.
+ */
+function project_info_legecy_form_validate($form, &$form_state) {
+ if (!PROJECT_INFO_LEGACY_DIRECTORY) {
+ form_set_error('op', t('The constant PROJECT_INFO_LEGACY_DIRECTORY must be set.'));
+ }
+}
+
+/**
+ * Start the batch to process legacy releases.
+ */
+function project_info_legecy_form_submit($form, &$form_state) {
+ $tids = array();
+ foreach ($form_state['values']['api'] as $tid => $selected) {
+ if ($selected) {
+ $tids[] = $tid;
+ }
+ }
+
+ $batch = array(
+ 'title' => t('Processing releases'),
+ 'operations' => array(
+ array('project_info_legacy_batch_operation_parse', array($tids)),
+ array('project_info_legacy_batch_operation_dependencies', array()),
+ ),
+ 'finished' => 'project_info_legacy_batch_finished',
+ 'init_message' => t('Determining releases to parse...'),
+ 'file' => drupal_get_path('module', 'project_info') . '/project_info.legacy.inc',
+ );
+ batch_set($batch);
+}
+
+/**
+ * Parse the modules contained within a project and their dependencies.
+ */
+function project_info_legacy_batch_operation_parse(array $tids, &$context) {
+ if (!isset($context['sandbox']['max'])) {
+ // First iteration, initialize working values.
+ $context['sandbox']['max'] = project_info_legacy_releases($tids, 0, TRUE);
+ $context['sandbox']['release_id'] = 0;
+ $context['sandbox']['progress'] = 0;
+ $context['results']['dependencies'] = array();
+ $context['results']['count'] = 0;
+ }
+
+ // Load the package include that contains functions to save and parse data.
+ module_load_include('package.inc', 'project_info');
+
+ $releases = project_info_legacy_releases($tids, $context['sandbox']['release_id']);
+ foreach ($releases as $release) {
+ if (($dependencies = project_info_legacy_process_release($release)) === FALSE) {
+ $context['results']['error'] = $release;
+ $context['finished'] = 1;
+ return;
+ }
+
+ $context['results']['dependencies'][$release['nid']] = $dependencies;
+
+ $context['sandbox']['release_id'] = $release['nid'];
+ $context['sandbox']['progress']++;
+ $context['results']['count']++;
+ }
+
+ $context['message'] = t('Last parsed %module release %tag (@progress of @max).',
+ array('%module' => $release['uri'], '%tag' => $release['tag'],
+ '@progress' => number_format($context['sandbox']['progress']), '@max' => number_format($context['sandbox']['max'])));
+
+ $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
+}
+
+/**
+ * Determine dependencies of releases.
+ */
+function project_info_legacy_batch_operation_dependencies(&$context) {
+ if (!isset($context['sandbox']['max'])) {
+ $context['sandbox']['max'] = count($context['results']['dependencies']);
+ $context['sandbox']['progress'] = 0;
+ }
+
+ // Load the package include that contains functions to save and parse data.
+ module_load_include('package.inc', 'project_info');
+
+ $i = 0;
+ foreach ($context['results']['dependencies'] as $rid => $dependencies) {
+ project_info_package_info_process_dependencies($rid, $dependencies);
+
+ // Remove already processed releases.
+ unset($context['results']['dependencies'][$rid]);
+
+ $context['sandbox']['progress']++;
+
+ // Only process 20 releases in a single batch operation.
+ if ($i++ == 20) {
+ break;
+ }
+ }
+
+ $context['message'] = t('Processed @progress of @max release dependencies.',
+ array('@progress' => number_format($context['sandbox']['progress']), '@max' => number_format($context['sandbox']['max'])));
+
+ $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
+}
+
+/**
+ * Display relevant finished message after batch run.
+ */
+function project_info_legacy_batch_finished($success, $results, $operations) {
+ if ($success && !isset($results['error'])) {
+ drupal_set_message(t('Processed @count release(s).', array('@count' => number_format($results['count']))));
+ }
+ else {
+ drupal_set_message(t('Failed to process @module release #@rid.',
+ array('@module' => $results['error']['uri'], '@rid' => $results['error']['nid'])), 'error');
+ }
+}
+
+/**
+ * Checkout a release and determine relevant information.
+ *
+ * Locate all .info files contained within the project, determine the names of
+ * the module(s) contained within the project and store the dependencies for
+ * later processing.
+ */
+function project_info_legacy_process_release(array $release) {
+ $directory_original = getcwd();
+
+ // Use legacy directory.
+ chdir(PROJECT_INFO_LEGACY_DIRECTORY);
+
+ // Clean directory.
+ exec('rm -r *');
+
+ // Checkout release.
+ if ($release['uri'] == 'drupal') {
+ $url = ':pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal';
+ $branch = $release['tag'];
+ $module = $release['uri'];
+ $directory = $release['uri'];
+ }
+ else {
+ $url = ':pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal-contrib';
+ $branch = $release['tag'];
+ $module = 'contributions/modules/' . $release['uri'];
+ $directory = $release['uri'];
+ }
+ exec("cvs -z6 -Q -d$url checkout -d$directory -r $branch $module", $output, $status);
+
+ // Return to original directory.
+ chdir($directory_original);
+
+ // Check for CVS checkout failure.
+ if ($status != 0) {
+ return FALSE;
+ }
+
+ // Scan checkout for .info files and create a list in the same format that
+ // project release uses, so that standard API functions can be used.
+ $files = file_scan_directory(PROJECT_INFO_LEGACY_DIRECTORY . '/' . $directory, '\.info$');
+ $info_files = array();
+ $dependencies = array();
+ foreach ($files as $file) {
+ $info_files[] = $file->filename;
+
+ $info = drupal_parse_info_file($file->filename);
+ if (!empty($info['dependencies'])) {
+ if (!is_array($info['dependencies'])) {
+ $info['dependencies'] = array($info['dependencies']);
+ }
+ $dependencies = array_merge($dependencies, $info['dependencies']);
+ }
+ }
+
+ // Clear previous records for the release.
+ project_info_package_list_clear($release['nid']);
+ project_info_package_dependency_clear($release['nid']);
+
+ // Store the list of modules contained by the project.
+ project_info_package_list_store($release['nid'], $info_files);
+
+ return array_unique($dependencies);
+}
+
+/**
+ * Select all 6.x or 7.x releases.
+ *
+ * Taxonomy term IDs 87 and 103 represent 6.x and 7.x releases.
+ *
+ * @return
+ * List of release information: rid, project uri, and cvs directory.
+ */
+function project_info_legacy_releases(array $tids, $release_id, $count = FALSE) {
+ $sql = 'SELECT ' . ($count ? 'COUNT(r.nid)' : 'r.nid, r.tag, p.uri, cp.directory') . '
+ FROM {project_release_nodes} r
+ INNER JOIN {node} n
+ ON r.nid = n.nid
+ INNER JOIN {term_node} t
+ ON n.vid = t.vid
+ INNER JOIN {project_projects} p
+ ON r.pid = p.nid
+ INNER JOIN {cvs_projects} cp
+ ON p.nid = cp.nid
+ WHERE t.tid IN (' . db_placeholders($tids, 'int') . ')
+ AND r.nid > %d';
+
+ $args = array_merge($tids, array($release_id));
+
+ if ($count) {
+ return db_result(db_query($sql, $args));
+ }
+
+ $sql .= ' ORDER BY r.nid';
+ $result = db_query_range($sql, $args, 0, 10);
+ $releases = array();
+ while ($release = db_fetch_array($result)) {
+ $releases[] = $release;
+ }
+ return $releases;
+}
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,163 @@
+= PROJECT_INFO_MINIMUM_API) {
+ // 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);
+
+ // Store list of dependencies.
+ project_info_package_info_process($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);
+}
+
+/**
+ * Determine and 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);
+
+ project_info_package_info_process_dependencies($rid, $info['dependencies']);
+ }
+}
+
+/**
+ * Store the list of dependencies for a release.
+ *
+ * @param $rid
+ * The project release ID.
+ * @param $dependencies
+ * List of dependencies.
+ */
+function project_info_package_info_process_dependencies($rid, array $dependencies) {
+ foreach ($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.legacy2.inc
===================================================================
RCS file: info/project_info.legacy2.inc
diff -N info/project_info.legacy2.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ info/project_info.legacy2.inc 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,275 @@
+ 'fieldset',
+ '#title' => t('Filter'),
+ );
+ $form['filter']['api'] = array(
+ '#type' => 'checkboxes',
+ '#title' => t('API'),
+ '#description' => t('Select the core API versions that releases must be compatible with.'),
+ '#options' => array(),
+ '#default_value' => array(),
+ );
+ $terms = project_release_get_api_taxonomy();
+ foreach ($terms as $term) {
+ $form['filter']['api']['#options'][$term->tid] = $term->name;
+
+ // Defaultly select
+ if (($major = array_shift(explode('.', $term->name, 2))) && $major >= PROJECT_INFO_MINIMUM_API) {
+ $form['filter']['api']['#default_value'][] = $term->tid;
+ }
+ }
+
+ $form['op'] = array(
+ '#type' => 'submit',
+ '#value' => t('Submit'),
+ );
+
+ return $form;
+}
+
+/**
+ * Ensure that the directory constant has been set.
+ */
+function project_info_legecy_form_validate($form, &$form_state) {
+ if (!PROJECT_INFO_LEGACY_DIRECTORY) {
+ form_set_error('op', t('The constant PROJECT_INFO_LEGACY_DIRECTORY must be set.'));
+ }
+}
+
+/**
+ * Start the batch to process legacy releases.
+ */
+function project_info_legecy_form_submit($form, &$form_state) {
+ $tids = array();
+ foreach ($form_state['values']['api'] as $tid => $selected) {
+ if ($selected) {
+ $tids[] = $tid;
+ }
+ }
+
+ $batch = array(
+ 'title' => t('Processing releases'),
+ 'operations' => array(
+ array('project_info_legacy_batch_operation_parse', array($tids)),
+ array('project_info_legacy_batch_operation_dependencies', array()),
+ ),
+ 'finished' => 'project_info_legacy_batch_finished',
+ 'init_message' => t('Determining releases to parse...'),
+ 'file' => drupal_get_path('module', 'project_info') . '/project_info.legacy.inc',
+ );
+ batch_set($batch);
+}
+
+/**
+ * Parse the modules contained within a project and their dependencies.
+ */
+function project_info_legacy_batch_operation_parse(array $tids, &$context) {
+ if (!isset($context['sandbox']['max'])) {
+ // First iteration, initialize working values.
+ $context['sandbox']['max'] = project_info_legacy_releases($tids, 0, TRUE);
+ $context['sandbox']['release_id'] = 0;
+ $context['sandbox']['progress'] = 0;
+ $context['results']['dependencies'] = array();
+ $context['results']['count'] = 0;
+ }
+
+ // Load the package include that contains functions to save and parse data.
+ module_load_include('package.inc', 'project_info');
+
+ $releases = project_info_legacy_releases($tids, $context['sandbox']['release_id']);
+ foreach ($releases as $release) {
+ if (($dependencies = project_info_legacy_process_release($release)) === FALSE) {
+ $context['results']['error'] = $release;
+ $context['finished'] = 1;
+ return;
+ }
+
+ $context['results']['dependencies'][$release['nid']] = $dependencies;
+
+ $context['sandbox']['release_id'] = $release['nid'];
+ $context['sandbox']['progress']++;
+ $context['results']['count']++;
+ }
+
+ $context['message'] = t('Last parsed %module release %tag (@progress of @max).',
+ array('%module' => $release['uri'], '%tag' => $release['tag'],
+ '@progress' => number_format($context['sandbox']['progress']), '@max' => number_format($context['sandbox']['max'])));
+
+ $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
+}
+
+/**
+ * Determine dependencies of releases.
+ */
+function project_info_legacy_batch_operation_dependencies(&$context) {
+ if (!isset($context['sandbox']['max'])) {
+ $context['sandbox']['max'] = count($context['results']['dependencies']);
+ $context['sandbox']['progress'] = 0;
+ }
+
+ // Load the package include that contains functions to save and parse data.
+ module_load_include('package.inc', 'project_info');
+
+ $i = 0;
+ foreach ($context['results']['dependencies'] as $rid => $dependencies) {
+ project_info_package_info_process_dependencies($rid, $dependencies);
+
+ // Remove already processed releases.
+ unset($context['results']['dependencies'][$rid]);
+
+ $context['sandbox']['progress']++;
+
+ // Only process 20 releases in a single batch operation.
+ if ($i++ == 20) {
+ break;
+ }
+ }
+
+ $context['message'] = t('Processed @progress of @max release dependencies.',
+ array('@progress' => number_format($context['sandbox']['progress']), '@max' => number_format($context['sandbox']['max'])));
+
+ $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
+}
+
+/**
+ * Display relevant finished message after batch run.
+ */
+function project_info_legacy_batch_finished($success, $results, $operations) {
+ if ($success && !isset($results['error'])) {
+ drupal_set_message(t('Processed @count release(s).', array('@count' => number_format($results['count']))));
+ }
+ else {
+ drupal_set_message(t('Failed to process @module release #@rid.',
+ array('@module' => $results['error']['uri'], '@rid' => $results['error']['nid'])), 'error');
+ }
+}
+
+/**
+ * Checkout a release and determine relevant information.
+ *
+ * Locate all .info files contained within the project, determine the names of
+ * the module(s) contained within the project and store the dependencies for
+ * later processing.
+ */
+function project_info_legacy_process_release(array $release) {
+ $directory_original = getcwd();
+
+ // Use legacy directory.
+ chdir(PROJECT_INFO_LEGACY_DIRECTORY);
+
+ // Clean directory.
+ exec('rm -r *');
+
+ // Checkout release.
+ if ($release['uri'] == 'drupal') {
+ $url = ':pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal';
+ $branch = $release['tag'];
+ $module = $release['uri'];
+ $directory = $release['uri'];
+ }
+ else {
+ $url = ':pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal-contrib';
+ $branch = $release['tag'];
+ $module = 'contributions/modules/' . $release['uri'];
+ $directory = $release['uri'];
+ }
+ exec("cvs -z6 -Q -d$url checkout -d$directory -r $branch $module", $output, $status);
+
+ // Return to original directory.
+ chdir($directory_original);
+
+ // Check for CVS checkout failure.
+ if ($status != 0) {
+ return FALSE;
+ }
+
+ // Scan checkout for .info files and create a list in the same format that
+ // project release uses, so that standard API functions can be used.
+ $files = file_scan_directory(PROJECT_INFO_LEGACY_DIRECTORY . '/' . $directory, '\.info$');
+ $info_files = array();
+ $dependencies = array();
+ foreach ($files as $file) {
+ $info_files[] = $file->filename;
+
+ $info = drupal_parse_info_file($file->filename);
+ if (!empty($info['dependencies'])) {
+ if (!is_array($info['dependencies'])) {
+ $info['dependencies'] = array($info['dependencies']);
+ }
+ $dependencies = array_merge($dependencies, $info['dependencies']);
+ }
+ }
+
+ // Clear previous records for the release.
+ project_info_package_list_clear($release['nid']);
+ project_info_package_dependency_clear($release['nid']);
+
+ // Store the list of modules contained by the project.
+ project_info_package_list_store($release['nid'], $info_files);
+
+ return array_unique($dependencies);
+}
+
+/**
+ * Select all 6.x or 7.x releases.
+ *
+ * Taxonomy term IDs 87 and 103 represent 6.x and 7.x releases.
+ *
+ * @return
+ * List of release information: rid, project uri, and cvs directory.
+ */
+function project_info_legacy_releases(array $tids, $release_id, $count = FALSE) {
+ $sql = 'SELECT ' . ($count ? 'COUNT(r.nid)' : 'r.nid, r.tag, p.uri, cp.directory') . '
+ FROM {project_release_nodes} r
+ INNER JOIN {node} n
+ ON r.nid = n.nid
+ INNER JOIN {term_node} t
+ ON n.vid = t.vid
+ INNER JOIN {project_projects} p
+ ON r.pid = p.nid
+ INNER JOIN {cvs_projects} cp
+ ON p.nid = cp.nid
+ WHERE t.tid IN (' . db_placeholders($tids, 'int') . ')
+ AND r.nid > %d';
+
+ $args = array_merge($tids, array($release_id));
+
+ if ($count) {
+ return db_result(db_query($sql, $args));
+ }
+
+ $sql .= ' ORDER BY r.nid';
+ $result = db_query_range($sql, $args, 0, 10);
+ $releases = array();
+ while ($release = db_fetch_array($result)) {
+ $releases[] = $release;
+ }
+ return $releases;
+}
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,137 @@
+ 'Parse legacy releases',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('project_info_legecy_form'),
+ 'access arguments' => array('project_info legacy parse'),
+ 'file' => 'project_info.legacy.inc',
+ 'type' => MENU_CALLBACK,
+ );
+
+ return $items;
+}
+
+/**
+ * Implementation of hook_perm().
+ */
+function project_info_perm() {
+ return array(
+ 'project_info legacy parse',
+ );
+}
+
+/**
+ * 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;
+}