diff --git a/versioncontrol_project_issue/plugins/event_processor/VersioncontrolEventProcessorGitIssueMapper.inc b/versioncontrol_project_issue/plugins/event_processor/VersioncontrolEventProcessorGitIssueMapper.inc index e524370..0c04203 100644 --- a/versioncontrol_project_issue/plugins/event_processor/VersioncontrolEventProcessorGitIssueMapper.inc +++ b/versioncontrol_project_issue/plugins/event_processor/VersioncontrolEventProcessorGitIssueMapper.inc @@ -27,44 +27,59 @@ class VersioncontrolEventProcessorGitIssueMapper implements VersioncontrolSynchr // No project associated. return; } + // We are depending on getCommitInterval(), so check we are using the right + // synchronization plugin. + $synchronizer = $event->getRepository()->getSynchronizer(); + if (!method_exists($synchronizer, 'getCommitInterval')) { + watchdog('versioncontrol_project_issue', 'git_issue_mapper: Cannot use a repository synchronizer of type %type', array('%type' => get_class($synchronizer)), WATCHDOG_WARNING); + return; + } + $operation_nid_maps = array(); foreach ($event as $ref) { if ($ref->reftype != VERSIONCONTROL_GIT_REFTYPE_BRANCH) { // Only process branch refs for now. return; } - //if ($ref->ff == 1) { - //// @fixme support non-ff. - //continue; - //} - //// @todo commits are not available anymore, use comit hooks? - //if ($ref->eventDeletedMe()) { - //// A label was removed. - //// @todo find related commits on vc_op_labels - //// @todo see if related commits are the only ones there. - //} - //if ($ref->eventCreatedMe()) { - //// @todo - //} - // Usual ff. This is bad, we are doing an incremental search doing a query - // on every iteration. Hopefully there is a way to avoid it. - - } - return; - // @fixme Follows code assuming we are iterating over known operation - // objects. Also to review. - $nids_on_message = $this->getIssuesFromMessage($operation->message); - if (count($nids_on_message) < 1) { - // Nothing to do. - return; - } - // Now see if they are really project issues. - $result = db_query("SELECT nid FROM {project_issues} WHERE pid = %d AND nid IN (%s)", $pid, implode(',', $nids_on_message)); - $operation_nid_maps = array(); - while ($row = db_fetch_object($result)) { - $operation_nid_maps[] = array( - 'nid' => $row->nid, - 'vc_op_id' => $operation->vc_op_id - ); + if ($ref->ff != 1) { + // @fixme support non-ff. + continue; + } + if ($ref->eventDeletedMe()) { + // Nothing to do. + // We could try to figure out orphaned commits from label removal. Let's + // trust on hook_versioncontrol_entity_commit_delete() for now. + continue; + } + // Usual ff ref update. + $commit_hashes = $synchronizer->getCommitInterval($ref->old_sha1, $ref->new_sha1); + // @todo Try to deal with big pushes loading operations in batches. + $related_operations = $event->getRepository()->loadCommits(array(), array('revision' => $commit_hashes)); + foreach ($related_operations as $operation) { + $nids_on_message = $this->getIssuesFromMessage($operation->message); + if (count($nids_on_message) < 1) { + // Nothing to do. + continue; + } + // Make sure we are dealing with project issues. + $possible_issues = node_load_multiple($nids_on_message); + foreach ($possible_issues as $possible_issue) { + if (!project_issue_node_is_issue($possible_issue)) { + continue; + } + // Associate only if repository project is the same than issue + // project. + if (empty($possible_issue->field_project[LANGUAGE_NONE][0]['target_id'])) { + continue; + } + if ($possible_issue->field_project[LANGUAGE_NONE][0]['target_id'] != $project_nid) { + continue; + } + $operation_nid_maps[] = array( + 'nid' => $possible_issue->nid, + 'vc_op_id' => $operation->vc_op_id + ); + } + } } if (empty($operation_nid_maps)) { // Nothing to do. @@ -82,7 +97,8 @@ class VersioncontrolEventProcessorGitIssueMapper implements VersioncontrolSynchr $this->repository = $repository; } - public function setConfiguration($data) { + public function setConfiguration($default_data) { + $this->messagePattern = !empty($default_data['message_pattern']) ? $default_data['message_pattern'] : ''; } public function buildForm($default_data) {