[Checkins] SVN: zc.recipe.macro/trunk/ Fixed bugs in the Manuelification of the QUICKSTART, and added result-sections.

Aaron Lehmann aaron at zope.com
Tue Jan 20 01:07:07 EST 2009


Log message for revision 94873:
  Fixed bugs in the Manuelification of the QUICKSTART, and added result-sections.
  
  

Changed:
  U   zc.recipe.macro/trunk/CHANGES.txt
  U   zc.recipe.macro/trunk/src/zc/recipe/macro/QUICKSTART.txt
  U   zc.recipe.macro/trunk/src/zc/recipe/macro/README.txt
  U   zc.recipe.macro/trunk/src/zc/recipe/macro/recipe.py
  U   zc.recipe.macro/trunk/src/zc/recipe/macro/tests.py

-=-
Modified: zc.recipe.macro/trunk/CHANGES.txt
===================================================================
--- zc.recipe.macro/trunk/CHANGES.txt	2009-01-20 04:11:10 UTC (rev 94872)
+++ zc.recipe.macro/trunk/CHANGES.txt	2009-01-20 06:07:06 UTC (rev 94873)
@@ -7,6 +7,8 @@
 - Removed version sections from the documentation.
 - Improved test coverage.
 - Put QUICKSTART.txt under test, using manuel.
+- Macro invocations will grow a result-sections value that lists the sections
+  they modified or created.
 
 1.2.4 (2008-07-18)
 ------------------

Modified: zc.recipe.macro/trunk/src/zc/recipe/macro/QUICKSTART.txt
===================================================================
--- zc.recipe.macro/trunk/src/zc/recipe/macro/QUICKSTART.txt	2009-01-20 04:11:10 UTC (rev 94872)
+++ zc.recipe.macro/trunk/src/zc/recipe/macro/QUICKSTART.txt	2009-01-20 06:07:06 UTC (rev 94873)
@@ -27,6 +27,7 @@
 
     [hard-rocker]
     recipe = zc.recipe.macro:empty
+    result-sections = hard-rocker
     rocking-style = so hard
     question = Why do I rock so hard?
 
@@ -56,6 +57,7 @@
 
     [hard-rocker]
     recipe = zc.recipe.macro:empty
+    result-sections = hard-rocker
     rocking-style = so hard
     question = Why do I rock so hard?
 
@@ -83,6 +85,7 @@
 
     [hard-rocker]
     recipe = zc.recipe.macro:empty
+    result-sections = hard-rocker
     question = Why do I rock so hard?
     rocking-style = so hard
 
@@ -123,16 +126,23 @@
 
 Result::
 
+    [rockers]
+    recipe = zc.recipe.macro:empty
+    result-sections = hard-rocker socks-rocker tired-rocker
+
     [hard-rocker]
     recipe = zc.recipe.macro:empty
+    rocking-style = so hard
     question = Why do I rock so hard?
 
     [socks-rocker]
     recipe = zc.recipe.macro:empty
+    rocking-style = my socks
     question = Why do I rock my socks?
 
     [tired-rocker]
     recipe = zc.recipe.macro:empty
+    rocking-style = all night
     question = Why do I rock all night?
 
 Special Variables
@@ -166,19 +176,24 @@
     targets =
         hard-rocker:hard-rocker-parameters
         socks-rocker:socks-rocker-parameters
-        rocking-style:tired-rocker-parameters
+        tired-rocker:tired-rocker-parameters
 
 Result::
 
+    [rockers]
+    recipe = zc.recipe.macro:empty
+    result-sections = hard-rocker socks-rocker tired-rocker
+
     [hard-rocker]
+    question = Why does hard-rocker rock so hard?
     recipe = zc.recipe.macro:empty
-    question = Why does hard-rocker rock so hard?
 
     [socks-rocker]
+    question = Why does socks-rocker rock my socks?
     recipe = zc.recipe.macro:empty
-    question = Why does socks-rocker rock my socks?
 
     [tired-rocker]
+    question = Why does tired-rocker rock all night?
     recipe = zc.recipe.macro:empty
-    question = Why does tired-rocker rock all night?
 
+Done Now.

Modified: zc.recipe.macro/trunk/src/zc/recipe/macro/README.txt
===================================================================
--- zc.recipe.macro/trunk/src/zc/recipe/macro/README.txt	2009-01-20 04:11:10 UTC (rev 94872)
+++ zc.recipe.macro/trunk/src/zc/recipe/macro/README.txt	2009-01-20 06:07:06 UTC (rev 94873)
@@ -101,6 +101,7 @@
                    'application': 'application',
                    'monitor-port': '8089',
                    'recipe': 'zc.recipe.macro:test',
+                   'result-sections': 'instance0',
                    'zope.conf': '
             <eventlog>
             <logfile>
@@ -114,6 +115,7 @@
                    'application': 'application',
                    'monitor-port': '9089',
                    'recipe': 'zc.recipe.macro:test',
+                   'result-sections': 'instance1',
                    'zope.conf': '
             <eventlog>
             <logfile>
@@ -184,6 +186,7 @@
                    'application': 'application',
                    'monitor-port': '8089',
                    'recipe': 'zc.recipe.macro:test',
+                   'result-sections': 'instance0',
                    'zope.conf': '
             <eventlog>
             <logfile>
@@ -197,6 +200,7 @@
                    'application': 'application',
                    'monitor-port': '9089',
                    'recipe': 'zc.recipe.macro:test',
+                   'result-sections': 'instance1',
                    'zope.conf': '
             <eventlog>
             <logfile>
@@ -264,6 +268,7 @@
                    'application': 'application',
                    'monitor-port': '8089',
                    'recipe': 'zc.recipe.macro:empty',
+                   'result-sections': 'instance0',
                    'zope.conf': '
             <eventlog>
             <logfile>
@@ -277,6 +282,7 @@
                    'application': 'application',
                    'monitor-port': '9089',
                    'recipe': 'zc.recipe.macro:empty',
+                   'result-sections': 'instance1',
                    'zope.conf': '
             <eventlog>
             <logfile>
@@ -341,6 +347,7 @@
                    'application': 'application',
                    'monitor-port': '8089',
                    'recipe': 'zc.recipe.macro:empty',
+                   'result-sections': 'instance0',
                    'zope.conf': '
             <eventlog>
             <logfile>
@@ -354,6 +361,7 @@
                    'application': 'application',
                    'monitor-port': '9089',
                    'recipe': 'zc.recipe.macro:empty',
+                   'result-sections': 'instance1',
                    'zope.conf': '
             <eventlog>
             <logfile>
@@ -395,7 +403,7 @@
     >>> buildout.install([])
     >>> buildout_pprint(buildout)
     {'buildout': {...},
-     'invoker': {'recipe': 'zc.recipe.macro:empty'},
+     'invoker': {'recipe': 'zc.recipe.macro:empty', 'result-sections': 'zero one'},
      'macro': {'output': 'I was invoked on $${:__name__}'},
      'one': {'output': 'I was invoked on one'},
      'zero': {'output': 'I was invoked on zero'}}
@@ -427,7 +435,7 @@
     >>> buildout.install([])
     >>> buildout_pprint(buildout)
     {'buildout': {...},
-     'invoker': {'recipe': 'zc.recipe.macro:empty'},
+     'invoker': {'recipe': 'zc.recipe.macro:empty', 'result-sections': 'zero one'},
      'macro': {'output': '$${:subject} was invoked on $${:__name__}'},
      'one': {'output': 'Fred was invoked on one'},
      'one-parameters': {'subject': 'Fred'},
@@ -484,6 +492,7 @@
                    'application': 'application',
                    'monitor-port': '8089',
                    'recipe': 'zc.recipe.macro:test',
+                   'result-sections': 'instance0',
                    'zope.conf': '
             <eventlog>
             <logfile>
@@ -516,7 +525,7 @@
     >>> buildout.install([])
     >>> buildout_pprint(buildout)
     {'buildout': {...},
-     'invoker': {'recipe': 'zc.recipe.macro:empty'},
+     'invoker': {'recipe': 'zc.recipe.macro:empty', 'result-sections': 'zero'},
      'macro': {'output': '$${:subject} $${:verb} on $${:__name__}',
                'subject': 'I',
                'verb': 'was invoked'},
@@ -584,6 +593,7 @@
                    'application': 'application',
                    'monitor-port': '8089',
                    'recipe': 'zc.recipe.macro:test',
+                   'result-sections': 'instance0',
                    'zope.conf': '
             <eventlog>
             <logfile>

Modified: zc.recipe.macro/trunk/src/zc/recipe/macro/recipe.py
===================================================================
--- zc.recipe.macro/trunk/src/zc/recipe/macro/recipe.py	2009-01-20 04:11:10 UTC (rev 94872)
+++ zc.recipe.macro/trunk/src/zc/recipe/macro/recipe.py	2009-01-20 06:07:06 UTC (rev 94873)
@@ -53,7 +53,9 @@
 
     macro_summation.update(dict(buildout[macro]))
 
+    new_sections = []
     for output, input in (parse_target(name, target) for target in targets):
+        new_sections.append(output)
         opt = Options(
                 buildout,
                 output,
@@ -68,6 +70,10 @@
             buildout._raw[output] = opt._raw
             #opt._initialize()
 
+    #Make a result-sections variable holding the sections that are modified
+    if new_sections:
+        options['result-sections'] = ' '.join(new_sections)
+
     #Make sure we have a recipe for this part, even if it is only the empty
     #one.
     if not options.get('recipe', None):

Modified: zc.recipe.macro/trunk/src/zc/recipe/macro/tests.py
===================================================================
--- zc.recipe.macro/trunk/src/zc/recipe/macro/tests.py	2009-01-20 04:11:10 UTC (rev 94872)
+++ zc.recipe.macro/trunk/src/zc/recipe/macro/tests.py	2009-01-20 06:07:06 UTC (rev 94873)
@@ -12,6 +12,7 @@
 #
 ##############################################################################
 
+import difflib
 import logging
 import os
 import os.path
@@ -81,35 +82,61 @@
 
 
 class BuildoutEvaluation(object):
-    def __init__(self, example, actual=None, desired=None, traceback=None):
+    def __init__(self, example, source=None, actual=None, desired=None, traceback=None):
         self.example = example
         self.traceback = traceback
+        self.actual = actual
+        self.desired = desired
         if traceback:
             self.passed = False
         else:
-            self.passed = True
-            self.successes = dict(desired)
-            self.failures = {}
-            for section_key, section in desired.iteritems():
-                if section_key not in actual:
-                    self.failures[section_key] = self.successes.pop(
-                        section_key)
-                    self.passed = False
-                else:
-                    for key, value in section.iteritems():
-                        if (key not in actual[section_key] or
-                            value != actual[section_key][key]):
-                            self.failures[section_key][key] = self.successes[
-                                section_key].pop(key)
-                            self.passed = False
+            # If there's no traceback, then we need to evaluate the results
+            # 1) The result begins as a copy of the full generated buildout
+            # 2) Sections and values that are not explicitly desired, and
+            #    and are present in the source are removed, since they
+            #    aren't interesting
+            # 3) The result should be equivalent to the desired dictionary
+            #    to pass
 
+            self.result = dict(actual)
+            for section_key, section in actual.iteritems():
+                if section_key in source:
+                    if section_key not in desired:
+                        del self.result[section_key]
+                    else:
+                        for key, value in dict(section).iteritems():
+                            if key in source[section_key]:
+                                if key not in desired[section_key]:
+                                    del self.result[section_key][key]
+            self.passed = self.result == self.desired
+
     def test_sections(self, actual, desired):
         return list(key for key in desired
             if key in actual and actual[key] == desired[key])
 
 
+def cfg_to_dict(cfg):
+    config = ConfigParser.RawConfigParser()
+    config.readfp(StringIO.StringIO(cfg))
+    return dict(
+        (section, dict(pair for pair in config.items(section)))
+        for section in config.sections())
+
+def dict_to_cfg(d):
+    cp = ConfigParser.RawConfigParser()
+    for section_name, section in d.iteritems():
+        cp.add_section(section_name)
+        for key, val in section.iteritems():
+            cp.set(section_name, key, val)
+    sio = StringIO.StringIO()
+    cp.write(sio)
+    cfg = sio.getvalue()
+    sio.close()
+    return cfg
+
+
 START_RE = re.compile(r'^Buildout::$', re.MULTILINE)
-END_RE = re.compile(r'(.+?)\n(?=\n\S).+?Result::(.+?)\n(?=\n\S*)',
+END_RE = re.compile(r'(.+?)\n(?=\n\S).+?Result::(.+?)\n(?=\n\S)',
     re.DOTALL)
 
 class BuildoutManuel(object):
@@ -136,13 +163,10 @@
             try:
                 buildout.install([])
                 result_buildout = dict(buildout)
-                config = ConfigParser.RawConfigParser()
-                config.readfp(StringIO.StringIO(example.want))
-                result_desired = dict(
-                    (section, dict(pair for pair in config.items(section)))
-                    for section in config.sections())
-                region.evaluated = BuildoutEvaluation(
-                    example, actual=result_buildout, desired=result_desired)
+                region.evaluated = BuildoutEvaluation(example,
+                                                      source=cfg_to_dict(example.source),
+                                                      actual=result_buildout,
+                                                      desired=cfg_to_dict(example.want))
             except zc.buildout.easy_install.MissingDistribution, md:
                 region.evaluated = BuildoutEvaluation(
                     example, traceback=''.join(
@@ -156,16 +180,11 @@
             if not evaluation.passed:
                 if evaluation.traceback:
                     region.formatted = evaluation.traceback
-#            else:
-#                cp = ConfigParser.RawConfigParser()
-#                for section_name, section in evaluation.successes.iteritems():
-#                    cp.add_section(section_name)
-#                    for key, val in section.iteritems():
-#                        cp.set(section_name, key, val)
-#                sio = StringIO.StringIO()
-#                cp.write(sio)
-#                region.formatted = sio.getvalue()
-#                sio.close()
+                else:
+                    region.formatted = '\n'.join(list(difflib.unified_diff(
+                        dict_to_cfg(evaluation.desired).split('\n'),
+                        dict_to_cfg(evaluation.result).split('\n'),
+                        'desired', 'result')))
 
     def setUp(self, test):
         self.test = test



More information about the Checkins mailing list