[Checkins] SVN: zc.buildout/branches/help-api/src/zc/buildout/ refactor description specific work in its own class

Godefroid Chapelle gotcha at bubblenet.be
Thu Jan 24 11:25:20 EST 2008


Log message for revision 83172:
  refactor description specific work in its own class
  test eggs that is not a recipe
  

Changed:
  U   zc.buildout/branches/help-api/src/zc/buildout/buildout.py
  U   zc.buildout/branches/help-api/src/zc/buildout/tests.py

-=-
Modified: zc.buildout/branches/help-api/src/zc/buildout/buildout.py
===================================================================
--- zc.buildout/branches/help-api/src/zc/buildout/buildout.py	2008-01-24 16:21:28 UTC (rev 83171)
+++ zc.buildout/branches/help-api/src/zc/buildout/buildout.py	2008-01-24 16:25:20 UTC (rev 83172)
@@ -20,10 +20,8 @@
 import logging
 import md5
 import os
-import pprint
 import re
 import shutil
-import cStringIO
 import sys
 import tempfile
 import urllib2
@@ -46,7 +44,7 @@
     """
 
 class MissingSection(zc.buildout.UserError, KeyError):
-    """A required section is missinh
+    """A required section is missing
     """
 
     def __str__(self):
@@ -805,62 +803,59 @@
     def describe(self, recipes):
         for recipe in recipes:
             recipe = recipe.strip()
-            recipe_spec = self._compute_recipe_and_version(recipe)
+            recipe_spec = self._get_recipe_with_version(recipe)
             recipe_class = self._get_recipe_class(recipe_spec)
-            if self._multiple_entry_points(recipe):
-                return
-            if recipe_class is not None:
-                self._describe_recipe(recipe, recipe_class)
+            description = Description(recipe, recipe_class)
+            description._print()
 
-    def _multiple_entry_points(self, name):
-        if ':' in name:
-            reqs, entry = name.split(':')
-        else:
-            reqs = name
-            entry = None    
- 
-        if entry is not None:
-            entries = list(pkg_resources.iter_entry_points('zc.buildout', entry))
-        else:
-            entries = list(pkg_resources.iter_entry_points('zc.buildout'))
-            
- 
-        entry_points = [entry_point for entry_point in 
-                        entries if entry_point.dist.project_name == reqs]
-        
-        if len(entry_points) > 1:
-            print '%s has multiple entry points:' % name
-            for entry_point in entry_points:
-                print '    %s' % entry_point.name
-            print "To get help about one of them use 'buildout",
-            print "describe %s:xxx'." % name
-            return True
-        else:
-            return False
-
-    def _get_recipe_class(self, name):
-        try:
-            reqs, entry = _recipe({'recipe': name})
-            return  _install_and_load(reqs, 'zc.buildout', entry, self)
-        except pkg_resources.DistributionNotFound:
-            return None
-
-    def _compute_recipe_and_version(self, name):
+    def _get_recipe_with_version(self, name):
         #if the recipe version is specified in versions section,
         #do nothing
-        if self.versions and name in self[self.versions].keys():
+        if (self.versions and 
+                name in self[self.versions].keys()):
             return name
         else:
             #iterate parts recipes
             parts = self['buildout']['parts'].split()
             recipes = [self[part]['recipe'] for part in parts]
             for recipe in recipes:
-            #and use first recipe name that holds a version spec
+            #and use first recipe self.name that holds a version spec
                 if name in recipe:
                     return recipe
         return name
 
-    def _print_docstring(self, docstring):
+    def _get_recipe_class(self, name):
+        try:
+            reqs, entry = _recipe({'recipe': name})
+            return  _install_and_load(reqs, 'zc.buildout', entry, self)
+        except (ImportError, pkg_resources.DistributionNotFound):
+            return None
+
+class Description(object):
+    def __init__(self, name, _class):
+        self.name = name
+        self._class = _class
+
+    def _print(self):
+        if self._class is None:
+            self.print_no_recipe()
+        else:
+            self.print_description()
+        if (not self.entrypoint_specified()) and self.has_multiple_entry_points():
+            self.print_multiple_entry_points()
+
+    def print_no_recipe(self):
+        print "'%s' is not a recipe." % self.name
+
+    def print_description(self):
+        print self.name
+        docstring = self._class.__doc__
+        if docstring is not None:
+            self.print_formatted_docstring(docstring)
+        else:
+            print '    No description available'
+
+    def print_formatted_docstring(self, docstring):
         lines = [line for line in docstring.splitlines()
                  if line is not None]
         if len(lines) < 2:
@@ -874,15 +869,26 @@
             for line in lines:
                 print line
 
-    def _describe_recipe(self, name, recipe_class):
-        docstring = recipe_class.__doc__
-        if docstring is not None:
-            print name
-            self._print_docstring(docstring)
-        else:
-            print name
-            print '    Help not available'
+    def entrypoint_specified(self):
+        return ':' in self.name
 
+    def has_multiple_entry_points(self):
+        entries = list(pkg_resources.iter_entry_points('zc.buildout'))
+ 
+        self.entry_points = [entry_point for entry_point in 
+                        entries if entry_point.dist.project_name == self.name]
+        
+        return len(self.entry_points) > 1
+
+    def print_multiple_entry_points(self):
+        print
+        print '%s has multiple entry points.' % self.name
+        print 'We have described the default entry point.'
+        print 'The other entry points are:'
+        for entry_point in self.entry_points:
+            if entry_point.name != 'default':
+                print '    %s' % entry_point.name
+
 def _install_and_load(spec, group, entry, buildout):
     __doing__ = 'Loading recipe %r.', spec
     try:

Modified: zc.buildout/branches/help-api/src/zc/buildout/tests.py
===================================================================
--- zc.buildout/branches/help-api/src/zc/buildout/tests.py	2008-01-24 16:21:28 UTC (rev 83171)
+++ zc.buildout/branches/help-api/src/zc/buildout/tests.py	2008-01-24 16:25:20 UTC (rev 83172)
@@ -641,14 +641,17 @@
     Let's call describe for zc.recipe.egg:
 
     >>> print system('%s describe zc.recipe.egg' % buildout)  
-    zc.recipe.egg has multiple entry points:
+    zc.recipe.egg
+        No description available
+    <BLANKLINE>
+    zc.recipe.egg has multiple entry points.
+    We have described the default entry point.
+    The other entry points are:
         develop
         script
-        default
         eggs
         custom
         scripts
-    To get help about one of them use 'buildout describe zc.recipe.egg:xxx'.
     <BLANKLINE>
 
     Now let's create our own recipe:
@@ -696,7 +699,7 @@
 
     >>> print system('%s describe my.recipes' % buildout) 
     my.recipes
-        Help not available
+        No description available
     <BLANKLINE>
 
     Let's add a docstring now:
@@ -769,10 +772,13 @@
     <BLANKLINE>
 
     >>> print system('%s describe my.recipes' % buildout) 
-    my.recipes has multiple entry points:
-        default
+    my.recipes
+        No description available
+    <BLANKLINE>
+    my.recipes has multiple entry points.
+    We have described the default entry point.
+    The other entry points are:
         second
-    To get help about one of them use 'buildout describe my.recipes:xxx'.
     <BLANKLINE>
 
     >>> print system('%s describe my.recipes:default' % buildout) 
@@ -783,7 +789,7 @@
 
     >>> print system('%s describe my.recipes:second' % buildout) 
     my.recipes:second
-        Help not available
+        No description available
     <BLANKLINE>
 
     >>> print system('%s describe my.recipes:default my.recipes:second' % buildout) 
@@ -791,13 +797,66 @@
         The coolest recipe on Earth.
         Ever.
     my.recipes:second
-        Help not available
+        No description available
     <BLANKLINE>
 
+    Let's call describe for an egg that cannot be installed:
 
+    >>> print system('%s describe foo.bar' % buildout)  
+    Couldn't find index page for 'foo.bar' (maybe misspelled?)
+    Getting distribution for 'foo.bar'.
+    While:
+      Installing recipe foo.bar.
+      Getting distribution for 'foo.bar'.
+    Error: Couldn't find a distribution for 'foo.bar'.
+    <BLANKLINE>
+    """
 
+def test_describe_egg_no_recipe():
     """
+    Let's create an egg that is not a recipe.
 
+    >>> mkdir(sample_buildout, 'my_egg')
+    >>> write(sample_buildout, 'my_egg', 'egg.py', 
+    ... '''
+    ... class MyEgg:
+    ...     pass
+    ... ''')
+
+    >>> write(sample_buildout, 'my_egg', 'setup.py',
+    ... '''
+    ... from setuptools import setup
+    ... setup(
+    ...     name = "my.egg",
+    ...     py_modules=['egg'],
+    ...     )
+    ... ''')
+
+    >>> write(sample_buildout, 'my_egg', 'README.txt', " ")
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... '''
+    ... [buildout]
+    ... develop = my_egg
+    ... parts = my.egg
+    ... [my.egg]
+    ... recipe = zc.recipe.egg
+    ... ''')
+
+    >>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
+
+    >>> print system(buildout),
+    Develop: '/sample-buildout/my_egg'
+    Installing my.egg.
+
+    Let's ask its description:
+
+    >>> print system('%s describe my.egg' % buildout) 
+    'my.egg' is not a recipe.
+    <BLANKLINE>
+
+    """
+
 def test_describe_versions():
     """
     Sometimes a recipe comes in two version in a buildout



More information about the Checkins mailing list