cvs diff: Diffing versioncontrol_release
Index: versioncontrol_release/versioncontrol_release.info
===================================================================
RCS file: /Users/wright/drupal/local_repo/contributions/modules/versioncontrol_project/versioncontrol_release/versioncontrol_release.info,v
retrieving revision 1.2
diff -u -p -r1.2 versioncontrol_release.info
--- versioncontrol_release/versioncontrol_release.info	6 Jan 2011 23:33:29 -0000	1.2
+++ versioncontrol_release/versioncontrol_release.info	7 Jan 2011 01:34:58 -0000
@@ -1,7 +1,10 @@
 ; $Id: versioncontrol_release.info,v 1.2 2011/01/06 23:33:29 dww Exp $
-name = "Version Control / Release Node integration"
+name = "Version Control / Release node integration"
 description = "Integrates release nodes (provided by the 'Project releases' module) with version control systems supported by the Version Control API."
+package = Version Control
 dependencies[] = versioncontrol_project
 dependencies[] = project_release
-package = Version Control
+dependencies[] = autoload
+dependencies[] = ctools
+files[] = includes/interfaces.inc
 core = 6.x
Index: versioncontrol_release/versioncontrol_release.module
===================================================================
RCS file: /Users/wright/drupal/local_repo/contributions/modules/versioncontrol_project/versioncontrol_release/versioncontrol_release.module,v
retrieving revision 1.12
diff -u -p -r1.12 versioncontrol_release.module
--- versioncontrol_release/versioncontrol_release.module	6 Jan 2011 23:33:29 -0000	1.12
+++ versioncontrol_release/versioncontrol_release.module	7 Jan 2011 02:04:59 -0000
@@ -64,79 +64,95 @@ function versioncontrol_release_admin_fo
   return system_settings_form($form);
 }
 
-
 /**
- * Return an object of version number values based on the given VCS label,
- * or FALSE if no version object can be constructed.
- *
- * If there is a local, site-specific implementation, use that.  Otherwise,
- * the tag is inserted directly into the "extra" field in the version object.
+ * Implement hook_ctools_plugin_directory().
  */
-function versioncontrol_release_get_version_from_label($label, $project_node) {
-  if (function_exists('versioncontrol_release_local_get_version_from_label')) {
-    return versioncontrol_release_local_get_version_from_label($label, $project_node);
+function versioncontrol_release_ctools_plugin_directory($module, $plugin) {
+  if ($module == 'versioncontrol_release' && $plugin == 'label_version_mapper') {
+    return "plugins/$plugin";
   }
-  // Try to provide a sensible default behavior by extracting number parts
-  // from the label name and using any non-numeric suffix as version extra.
-  $fields = array('version_major', 'version_minor', 'version_patch');
-  $version = array();
-
-  $matched = preg_match_all('/[^\.\-]+/', $label['name'], $matches, PREG_OFFSET_CAPTURE);
-  $label_parts = $matched ? $matches[0] : array();
-
-  while (!empty($fields)) { // Try to fill all regular version fields.
-    $current_field = array_shift($fields);
+}
 
-    while (!empty($label_parts)) {
-      $label_part = array_shift($label_parts);
+/**
+ * Instantiate an object to map VCAPI labels into release node version objects.
+ *
+ * This function looks in the project's VCAPI repository object for the
+ * 'plugins' array and finds the desired CTools plugin for the label/version
+ * mapping. It then loads the plugin and instantiates a mapper object. If
+ * anything goes wrong, we return FALSE.
+ *
+ * @param $project_node
+ *   The fully loaded node object for the project we're doing the mapping for.
+ *
+ * @return object
+ *   The specific elements of the version that a given VCAPI label maps to.
+ *   Can use any of the following fields: 'version_major', 'version_minor',
+ *   'verion_patch', 'version_extra', or 'version_api_tid'.
+ *
+ * @see project_release_get_version()
+ * @see VersioncontrolReleaseLabelVersionMapperInterface
+ */
+function versioncontrol_release_get_label_version_mapper($project_node) {
+  ctools_include('plugins');
 
-      if (is_numeric($label_part[0])) {
-        $version[$current_field] = $label_part[0];
-        break; // next version field
-      }
-      elseif (!empty($version)) {
-        // Non-numeric field after a numeric one was already assigned:
-        // that sounds like a suffix like "beta1" or similar. Put back the
-        // current label part so that it can still be extracted afterwards,
-        // and fill up the regular fields in order to exit both loops.
-        array_unshift($label_parts, $label_part);
-        while (!empty($fields)) {
-          $remaining_field = array_shift($fields);
-          $version[$remaining_field] = FALSE;
+  if (!empty($project_node->versioncontrol_project['repo'])) {
+    $repo = $project_node->versioncontrol_project['repo'];
+    if (!empty($repo->plugins['versioncontrol_release_label_version_mapper'])) {
+      $plugins = ctools_get_plugins('versioncontrol_release', 'label_version_mapper');
+      foreach ($plugins as $plugin_name => $plugin_definition) {
+        if ($plugin_name == $repo->plugins['versioncontrol_release_label_version_mapper']) {
+          $class = ctools_plugin_get_class($plugin_definition, 'handler');
+          $mapper = new $class();
+          return $mapper;
         }
-        break;
       }
     }
   }
+  return FALSE;
+}
 
-  // Remove any fields padded with FALSE.
-  $positive_version_numbers = FALSE;
-  foreach ($version as $field => $number) {
-    if ($number === FALSE) {
-      unset($version[$field]);
-    }
-    elseif ($number > 0) {
-      $positive_version_numbers = TRUE;
-    }
-  }
+/**
+ * Map a VCAPI tag into an object of version information.
+ *
+ * @param VersioncontrolTag $tag
+ *   An object representing a version control tag.
+ * @param $project_node
+ *   The fully loaded node object for the project we're doing the mapping for.
+ *
+ * @return object
+ *   The specific elements of the version that a given VCAPI label maps to.
+ *   Can use any of the following fields: 'version_major', 'version_minor',
+ *   'verion_patch', 'version_extra', or 'version_api_tid'.
+ *
+ * @see project_release_get_version()
+ * @see versioncontrol_release_get_label_version_mapper()
+ * @see VersioncontrolReleaseLabelVersionMapperInterface
+ */
+function versioncontrol_release_get_version_from_tag($tag, $project_node) {
+  $mapper = versioncontrol_release_get_label_version_mapper();
+  return $mapper->GetVersionFromTag($tag, $project_node);
+}
 
-  if (!empty($positive_version_numbers)) {
-    if ($label['type'] == VERSIONCONTROL_OPERATION_BRANCH) {
-      // Branches always get a "-dev" appended. Looks good, and helps with
-      // reverse engineering the version number.
-      $version['version_extra'] = 'dev';
-    }
-    elseif (!empty($label_parts)) {
-      // The next label part is the one after the last numeric part, like "beta1".
-      // From that position on, use the rest of $label['name'] as version extra.
-      $label_part = array_shift($label_parts);
-      $version['version_extra'] = substr($label['name'], $label_part[1]);
-    }
-    return (object) $version;
-  }
-  else {
-    return empty($version) ? FALSE : ((object) $version);
-  }
+/**
+ * Map a VCAPI branch into an object of version information.
+ *
+ * @param VersioncontrolBranch $branch
+ *   An object representing a version control branch.
+ * @param $project_node
+ *   The fully loaded node object for the project we're doing the mapping for.
+ *
+ * @return object
+ *   The specific elements of the version that a given VCAPI label maps to.
+ *   Can use any of the following fields: 'version_major', 'version_minor',
+ *   'verion_patch', 'version_extra', or 'version_api_tid'.
+ *
+ * @see project_release_get_version()
+ * @see versioncontrol_release_get_label_version_mapper()
+ * @see VersioncontrolReleaseLabelVersionMapperInterface
+ */
+function versioncontrol_release_get_version_from_branch($branch, $project_node) {
+  $mapper = versioncontrol_release_get_label_version_mapper();
+  return $mapper->GetVersionFromBranch($branch, $project_node);
 }
 
 /**
@@ -212,7 +228,6 @@ function versioncontrol_release_get_labe
   }
 }
 
-
 /**
  * Implementation of hook_form_alter().
  * We do this instead of hook_form_[form_id]_alter() because it gets called
cvs diff: Diffing versioncontrol_release/includes
Index: versioncontrol_release/includes/interfaces.php
===================================================================
RCS file: versioncontrol_release/includes/interfaces.php
diff -N versioncontrol_release/includes/interfaces.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ versioncontrol_release/includes/interfaces.php	7 Jan 2011 01:33:41 -0000
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file Interfaces for the Version Control Release integration module.
+ */
+
+/**
+ * Map VCAPI labels (branches and tags) into project release versions.
+ */
+interface VersioncontrolReleaseLabelVersionMapperInterface {
+  /**
+   * Return an object with version fields for a given VCAPI tag.
+   *
+   * @param VersioncontrolTag $tag
+   *   An object representing a version control tag.
+   *
+   * @param $project_node
+   *   The full node object for the project we're doing the mapping for.
+   *
+   * @return object
+   *   The specific elements of the version that a given VCAPI tag maps to.
+   *   Can use any of the following fields: 'version_major', 'version_minor',
+   *   'verion_patch', 'version_extra', or 'version_api_tid'. Returns FALSE if
+   *   we can't parse the tag name and figure out the version fields.
+   *
+   * @see project_release_get_version()
+   */
+  function GetVersionFromTag($tag, $project_node);
+
+  /**
+   * Return an object with version fields for a given VCAPI branch.
+   *
+   * @param VersioncontrolBranch $branch
+   *   An object representing a version control branch.
+   *
+   * @param $project_node
+   *   The full node object for the project we're doing the mapping for.
+   *
+   * @return object
+   *   The specific elements of the version that a given VCAPI branch maps to.
+   *   Can use any of the following fields: 'version_major', 'version_minor',
+   *   'verion_patch', 'version_extra', or 'version_api_tid'. Returns FALSE if
+   *   we can't parse the branch name and figure out the version fields.
+   *
+   * @see project_release_get_version()
+   */
+  function GetVersionFromBranch($branch, $project_node);
+}
cvs diff: Diffing versioncontrol_release/plugins
cvs diff: Diffing versioncontrol_release/plugins/label_version_mapper
Index: versioncontrol_release/plugins/label_version_mapper/VersioncontrolReleaseLabelVersionMapperGeneric.class.php
===================================================================
RCS file: versioncontrol_release/plugins/label_version_mapper/VersioncontrolReleaseLabelVersionMapperGeneric.class.php
diff -N versioncontrol_release/plugins/label_version_mapper/VersioncontrolReleaseLabelVersionMapperGeneric.class.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ versioncontrol_release/plugins/label_version_mapper/VersioncontrolReleaseLabelVersionMapperGeneric.class.php	7 Jan 2011 01:43:24 -0000
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * Plugin to do very simple mapping of tags and branches to versions.
+ *
+ * Tries to provide a sensible default behavior by extracting number parts
+ * from the label name and using any non-numeric suffix as version extra.
+ */
+class VersioncontrolReleaseLabelVersionMapperGeneric implements VersioncontrolReleaseLabelVersionMapperInterface {
+
+  public function GetVersionFromTag($tag, $project_node) {
+    return GetVersionFromLabel($tag->name(), VERSIONCONTROL_LABEL_TAG);
+  }
+
+  public function GetVersionFromBranch($branch, $project_node) {
+    return GetVersionFromLabel($branch->name(), VERSIONCONTROL_LABEL_BRANCH);
+  }
+
+  protected function GetVersionFromLabel($label_name, $label_type, $project_node) {
+    $fields = array('version_major', 'version_minor', 'version_patch');
+    $version = array();
+
+    $matched = preg_match_all('/[^\.\-]+/', $label_name, $matches, PREG_OFFSET_CAPTURE);
+    $label_parts = $matched ? $matches[0] : array();
+
+    while (!empty($fields)) { // Try to fill all regular version fields.
+      $current_field = array_shift($fields);
+
+      while (!empty($label_parts)) {
+        $label_part = array_shift($label_parts);
+
+        if (is_numeric($label_part[0])) {
+          $version[$current_field] = $label_part[0];
+          break; // next version field
+        }
+        elseif (!empty($version)) {
+          // Non-numeric field after a numeric one was already assigned:
+          // that sounds like a suffix like "beta1" or similar. Put back the
+          // current label part so that it can still be extracted afterwards,
+          // and fill up the regular fields in order to exit both loops.
+          array_unshift($label_parts, $label_part);
+          while (!empty($fields)) {
+            $remaining_field = array_shift($fields);
+            $version[$remaining_field] = FALSE;
+          }
+          break;
+        }
+      }
+    }
+
+    // Remove any fields padded with FALSE.
+    $positive_version_numbers = FALSE;
+    foreach ($version as $field => $number) {
+      if ($number === FALSE) {
+        unset($version[$field]);
+      }
+      elseif ($number > 0) {
+        $positive_version_numbers = TRUE;
+      }
+    }
+
+    if (!empty($positive_version_numbers)) {
+      if ($label_type == VERSIONCONTROL_OPERATION_BRANCH) {
+        // Branches always get a "-dev" appended. Looks good, and helps with
+        // reverse engineering the version number.
+        $version['version_extra'] = 'dev';
+      }
+      elseif (!empty($label_parts)) {
+        // The next label part is the one after the last numeric part, like
+        // "beta1". From that position on, use the rest of $label['name'] as
+        // version extra.
+        $label_part = array_shift($label_parts);
+        $version['version_extra'] = substr($label['name'], $label_part[1]);
+      }
+      return (object) $version;
+    }
+    else {
+      return empty($version) ? FALSE : ((object) $version);
+    }
+  }
+}
Index: versioncontrol_release/plugins/label_version_mapper/generic.inc
===================================================================
RCS file: versioncontrol_release/plugins/label_version_mapper/generic.inc
diff -N versioncontrol_release/plugins/label_version_mapper/generic.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ versioncontrol_release/plugins/label_version_mapper/generic.inc	7 Jan 2011 01:18:24 -0000
@@ -0,0 +1,8 @@
+<?php
+
+$plugin = array(
+  'title' => t('Map using generic numeric logic'),
+  'mapper' => array(
+    'class' => 'VersioncontrolReleaseLabelVersionMapperGeneric',
+  ),
+);
cvs diff: Diffing versioncontrol_release/scripts
