Switch to side-by-side view

--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -27,11 +27,19 @@
 
 class ProjectImporter(BaseController):
     """
+    Base class for project importers.
+
+    Subclases are required to implement the :meth:`index()` and
+    :meth:`process()` views described below.
     """
     source = None
 
     @LazyProperty
     def tool_importers(self):
+        """
+        List of all tool importers that import from the same source
+        as this project importer.
+        """
         tools = {}
         for ep in iter_entry_points('allura.importers'):
             epv = ep.load()
@@ -43,7 +51,7 @@
         """
         Override and expose this view to present the project import form.
 
-        The template used by this view should extend the base template in:
+        The template used by this view should extend the base template in::
 
             jinja:forgeimporters:templates/project_base.html
 
@@ -65,6 +73,29 @@
 
 class ToolImporter(object):
     """
+    Base class for tool importers.
+
+    Subclasses are required to implement :meth:`import_tool()` described
+    below and define the following attributes:
+
+    .. py:attribute:: target_app
+
+       A reference or list of references to the tool(s) that this imports
+       to.  E.g.::
+
+            target_app = [forgegit.ForgeGitApp, forgehg.ForgeHgApp]
+
+    .. py:attribute:: source
+
+       A string indicating where this imports from.  This must match the
+       `source` value of the :class:`ProjectImporter` for this importer to
+       be discovered during full-project imports.  E.g.::
+
+            source = 'Google Code'
+
+    .. py:attribute:: controller
+
+       The controller for this importer, to handle single tool imports.
     """
     target_app = None  # app or list of apps
     source = None  # string description of source, must match project importer
@@ -72,11 +103,17 @@
 
     @classmethod
     def by_name(self, name):
+        """
+        Return a ToolImporter subclass instance given its entry-point name.
+        """
         for ep in iter_entry_points('allura.importers', name):
             return ep.load()()
 
     @classmethod
     def by_app(self, app):
+        """
+        Return a ToolImporter subclass instance given its target_app class.
+        """
         importers = {}
         for ep in iter_entry_points('allura.importers'):
             importer = ep.load()
@@ -84,18 +121,31 @@
                 importers[ep.name] = importer()
         return importers
 
-    def import_tool(self, project=None, mount_point=None):
+    def import_tool(self, project, project_name, mount_point=None, mount_label=None):
         """
         Override this method to perform the tool import.
+
+        :param project: the Allura project to import to
+        :param project_name: the name of the remote project to import from
+        :param mount_point: the mount point name, to override the default
+        :param mount_label: the mount label name, to override the default
         """
         raise NotImplementedError
 
     @property
     def tool_label(self):
+        """
+        The label for this tool importer.  Defaults to the `tool_label` from
+        the `target_app`.
+        """
         return getattr(aslist(self.target_app)[0], 'tool_label', None)
 
     @property
     def tool_description(self):
+        """
+        The description for this tool importer.  Defaults to the `tool_description`
+        from the `target_app`.
+        """
         return getattr(aslist(self.target_app)[0], 'tool_description', None)
 
     def tool_icon(self, theme, size):
@@ -103,6 +153,12 @@
 
 
 class ToolsValidator(fev.Set):
+    """
+    Validates the list of tool importers during a project import.
+
+    This verifies that the tools selected are available and valid
+    for this source.
+    """
     def __init__(self, source, *a, **kw):
         super(ToolsValidator, self).__init__(*a, **kw)
         self.source = source