You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@gump.apache.org by le...@apache.org on 2005/07/04 15:54:29 UTC

svn commit: r209079 - in /gump/branches/Gump3: ./ bin/pylid-0.3/ pygump/ pygump/python/ pygump/python/gump/engine/ pygump/python/gump/model/ pygump/python/gump/plugins/ pygump/python/gump/test/ pygump/python/gump/util/

Author: leosimons
Date: Mon Jul  4 06:54:27 2005
New Revision: 209079

URL: http://svn.apache.org/viewcvs?rev=209079&view=rev
Log:
Sorry for the big commit, but I have some old stuff in a seperate development tree on my laptop that really needed to make it into this branch now. Changes:

 * Make testcases a little more robust and less verbose

 * Change finalize() signature for plugins to pass in the workspace

 * Make ExceptionInfo a core model object

 * Start work on a brain-dead-simple persistence module that saves the entire workspace on a pickle shelf. Without knowing exactly what to push to the SQL database, this means we can be 'sure' to save 'everything', which Stefano or his librarian friends c
an then put on big hard disks for later analysis. Moreover, it should be a simpler way (without having to do the object->relational->object translation) to implement the 'last successful build' part of our algorithm (hooks are there now).

 * util/sysinfo is more system-specific than I hoped. /proc/xxxinfo only exists on linux.

 * make the commandline failures provide useful (I hope) clues.

 * Make pylids import-everything actually work

Added:
    gump/branches/Gump3/pygump/python/gump/engine/persistence.py
      - copied, changed from r169268, gump/branches/Gump3/pygump/python/gump/engine/loader.py
    gump/branches/Gump3/pygump/python/main.py
      - copied, changed from r202450, gump/branches/Gump3/pygump/main.py
Removed:
    gump/branches/Gump3/pygump/main.py
Modified:
    gump/branches/Gump3/bin/pylid-0.3/pylid.py
    gump/branches/Gump3/gump
    gump/branches/Gump3/pygump/python/gump/engine/algorithm.py
    gump/branches/Gump3/pygump/python/gump/engine/walker.py
    gump/branches/Gump3/pygump/python/gump/model/__init__.py
    gump/branches/Gump3/pygump/python/gump/model/util.py
    gump/branches/Gump3/pygump/python/gump/plugins/__init__.py
    gump/branches/Gump3/pygump/python/gump/plugins/logreporter.py
    gump/branches/Gump3/pygump/python/gump/test/testDynagumper.py
    gump/branches/Gump3/pygump/python/gump/test/testUtilIO.py
    gump/branches/Gump3/pygump/python/gump/test/testUtilMysql.py
    gump/branches/Gump3/pygump/python/gump/util/sysinfo.py

Modified: gump/branches/Gump3/bin/pylid-0.3/pylid.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/bin/pylid-0.3/pylid.py?rev=209079&r1=209078&r2=209079&view=diff
==============================================================================
--- gump/branches/Gump3/bin/pylid-0.3/pylid.py (original)
+++ gump/branches/Gump3/bin/pylid-0.3/pylid.py Mon Jul  4 06:54:27 2005
@@ -280,6 +280,7 @@
         dirName, fileName = os.path.split(path)
         sys.path.insert(0, dirName)
         modname = os.path.splitext(os.path.basename(fileName))[0]
+        modname = modname.replace(os.path.sep, ".")
         if coverage:
             self.cov.start()
         module = __import__(modname)
@@ -312,6 +313,10 @@
         if(fileName.startswith(os.path.sep)):
             fileName = fileName[1:]
         modname = os.path.splitext(fileName)[0]
+        modname = modname.replace(os.path.sep, ".")
+        pidx = modname.rfind(".")
+        if pidx != -1:
+          __import__(modname[:pidx])
         self.cov.start()
         module = __import__(modname)
         self.cov.stop()

Modified: gump/branches/Gump3/gump
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/gump?rev=209079&r1=209078&r2=209079&view=diff
==============================================================================
--- gump/branches/Gump3/gump (original)
+++ gump/branches/Gump3/gump Mon Jul  4 06:54:27 2005
@@ -471,6 +471,7 @@
   check_pylib "MySQLdb" "http://sourceforge.net/projects/mysql-python"
   check_pylib "pmock" "http://pmock.sourceforge.net/"
   check_pylib "subprocess" "http://www.lysator.liu.se/~astrand/popen5/"
+  #check_pylib "irclib" "http://sourceforge.net/projects/python-irclib"
 }
 
 # create a .pid file
@@ -664,8 +665,8 @@
       `cygpath -w $GUMP_HOME/pygump/python/gump/test` $@
   else
     $GUMP_PYTHON $GUMP_HOME/bin/pylid-0.3/pylid.py -c -v \
-      -b $GUMP_HOME/pygump -b $GUMP_HOME/pygump/python \
-      -i $GUMP_HOME/pygump -i $GUMP_HOME/pygump/python \
+      -b $GUMP_HOME/pygump/python \
+      -i $GUMP_HOME/pygump/python \
       -e $GUMP_HOME/pygump/python/gump/test \
       $GUMP_HOME/pygump/python/gump/test $@
   fi

Modified: gump/branches/Gump3/pygump/python/gump/engine/algorithm.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/engine/algorithm.py?rev=209079&r1=209078&r2=209079&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/engine/algorithm.py (original)
+++ gump/branches/Gump3/pygump/python/gump/engine/algorithm.py Mon Jul  4 06:54:27 2005
@@ -35,21 +35,14 @@
 import sys
 
 from gump.util import ansicolor
-from gump.model import ModelObject, CvsModule
+from gump.model import ModelObject, CvsModule, ExceptionInfo, Jar
 from gump.model.util import mark_failure, check_failure, mark_skip, check_skip
 from gump.model.util import mark_whether_module_was_updated
+from gump.model.util import check_module_update_failure
+from gump.model.util import store_exception
 
 from gump.model.util import UPDATE_TYPE_CHECKOUT, UPDATE_TYPE_UPDATE
 
-class ExceptionInfo(ModelObject):
-    def __init__(self, type, value, traceback):
-        self.type = type
-        self.value = value
-        self.traceback = traceback
-    
-    def __str__(self):
-        return "<%s:%s>" % (self.type, self.value)
-
 class BaseErrorHandler:
     """Base error handler for use with the various algorithms.
     
@@ -66,11 +59,15 @@
     This handler logs then just re-raises a caught error.
     """
     def __init__(self, log):
+        assert hasattr(log, "exception")
+        assert callable(log.exception)
+        
         self.log = log
 
     def handle(self, visitor, visited_model_object, type, value, traceback):
-        """Override this method to be able to swallow exceptions."""
-        self.log.exception("%s threw an exception while visiting %s!" % (visitor, visited_model_object))
+        """Log the exception, then re-raise it."""
+        self.log.exception("%s threw an exception while visiting %s!" % \
+                           (visitor, visited_model_object))
         raise type, value
 
 class OptimisticLoggingErrorHandler:
@@ -79,19 +76,34 @@
     This handler logs a caught error then stores it on the model.
     """
     def __init__(self, log):
+        assert hasattr(log, "exception")
+        assert callable(log.exception)
+        
         self.log = log
 
     def handle(self, visitor, visited_model_object, type, value, traceback):
-        """Override this method to be able to swallow exceptions."""
-        self.log.exception("%s%s threw an exception while visiting %s!%s" % (ansicolor.Bright_Red, visitor, visited_model_object, ansicolor.Black))
+        """Swallow the exception, storing it with the model."""
+        self.log.exception("%s%s threw an exception while visiting %s!%s" % \
+                (ansicolor.Bright_Red, visitor, visited_model_object, ansicolor.Black))
         if isinstance(visited_model_object, ModelObject):
-            if not hasattr(visited_model_object, 'exceptions'):
-                visited_model_object.exceptions = []
-            visited_model_object.exceptions.append( ExceptionInfo(type, value, traceback) )
+            store_exception(type, value, traceback)
 
 class DumbAlgorithm:
     """"Core" algorithm that simply redirects all visit_XXX calls to other plugins."""
     def __init__(self, plugin_list, error_handler=BaseErrorHandler()):
+        assert isinstance(plugin_list, list)
+        for visitor in plugin_list:
+            assert hasattr(visitor, "_initialize")
+            assert callable(visitor._initialize)
+            assert hasattr(visitor, "_visit_workspace")
+            assert callable(visitor._visit_workspace)
+            assert hasattr(visitor, "_visit_repository")
+            assert callable(visitor._visit_repository)
+            assert hasattr(visitor, "_visit_module")
+            assert callable(visitor._visit_module)
+            assert hasattr(visitor, "_visit_project")
+            assert callable(visitor._visit_project)
+            
         self.list = plugin_list
         self.error_handler = error_handler
     
@@ -100,7 +112,8 @@
             try: visitor._initialize()
             except:
                 (type, value, traceback) = sys.exc_info()
-                self.error_handler.handle(visitor, "{{{initialization stage}}}", type, value, traceback)
+                self.error_handler.handle(visitor, \
+                        "{{{initialization stage}}}", type, value, traceback)
 
     def _visit_workspace(self, workspace):
         for visitor in self.list:
@@ -130,12 +143,24 @@
                 (type, value, traceback) = sys.exc_info()
                 self.error_handler.handle(visitor, project, type, value, traceback)
 
-    def _finalize(self):
+    def _finalize(self, workspace):
         for visitor in self.list:
-            try: visitor._finalize()
+            try:
+                visitor._finalize(workspace)
             except:
                 (type, value, traceback) = sys.exc_info()
-                self.error_handler.handle(visitor, "{{{finalization stage}}}", type, value, traceback)
+                self.error_handler.handle(visitor, \
+                        "{{{finalization stage}}}", type, value, traceback)
+
+class NoopPersistenceHelper:
+    def use_previous_build(self, arg):
+        pass
+    
+    def has_previous_build(self, arg):
+        pass
+    
+    def stop_using_previous_build(self, arg):
+        pass
 
 class MoreEfficientAlgorithm(DumbAlgorithm):
     """Algorithm that implements a more efficient build algorithm.
@@ -153,6 +178,14 @@
     array named "failure_cause" will be created pointing to the elements that
     "caused" them to fail.
     """
+    def __init__(self, plugin_list, error_handler=BaseErrorHandler(), persistence_helper=NoopPersistenceHelper()):
+        DumbAlgorithm.__init__(self, plugin_list, error_handler)
+        
+        if persistence_helper != None:
+          assert hasattr(persistence_helper, "use_previous_build")
+          assert callable(persistence_helper.use_previous_build)
+          self.persistence_helper = persistence_helper
+        
     def _visit_module(self, module):
         # run the delegates
         try:
@@ -164,7 +197,7 @@
             mark_failure(module, module.exceptions[len(module.exceptions)-1])
         
         # check for update errors
-        if getattr(module, "update_exit_status", False):
+        if check_module_update_failure(module):
             mark_failure(module, module)
             # if module update failed, don't try and attempt to build contained
             # projects either.
@@ -183,7 +216,12 @@
         # check for dependencies that failed to build
         for relationship in project.dependencies:
             if check_failure(relationship.dependency):
-                mark_failure(project, relationship)
+                # if there is a "last successful build", we'll use that
+                if self.persistence_helper.has_previous_build(project):
+                    self.persistence_helper.use_previous_build(relationship.dependency)
+                else:
+                    # otherwise, we're doomed!
+                    mark_failure(project, relationship)
 
         # don't build if its not going to do any good
         if not check_failure(project) and not check_skip(project):
@@ -198,5 +236,8 @@
             # blame commands that went awry
             for command in project.commands:
                 if getattr(command, "build_exit_status", False):
-                    #mark_failure(command, command)
                     mark_failure(project, command)
+    
+    def _finalize(self, workspace):
+        DumbAlgorithm._finalize(self, workspace)
+        self.persistence_helper.stop_using_previous_build(workspace)
\ No newline at end of file

Copied: gump/branches/Gump3/pygump/python/gump/engine/persistence.py (from r169268, gump/branches/Gump3/pygump/python/gump/engine/loader.py)
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/engine/persistence.py?p2=gump/branches/Gump3/pygump/python/gump/engine/persistence.py&p1=gump/branches/Gump3/pygump/python/gump/engine/loader.py&r1=169268&r2=209079&rev=209079&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/engine/loader.py (original)
+++ gump/branches/Gump3/pygump/python/gump/engine/persistence.py Mon Jul  4 06:54:27 2005
@@ -14,215 +14,134 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""This module reads gump xml metadata."""
+#    Information from previous projects can be stored using the store_previous_build()
+#    method. It can be used in place of the "current build" using use_previous_build()
+#    if has_previous_build() shows there actually was a build stored, and then everything
+#    can be restored to normal using stop_using_previous_build().
 
-__copyright__ = "Copyright (c) 2004-2005 The Apache Software Foundation"
-__license__   = "http://www.apache.org/licenses/LICENSE-2.0"
-
-import logging
+from gump.model.util import get_project_directory
 import os
 
-from xml import dom
-from xml.dom import minidom
-
-from gump.engine import EngineError
-from gump.engine.modeller import _import_node
-from gump.engine.modeller import _find_project_containing_node
-from gump.engine.modeller import _find_document_containing_node
-from gump.engine.modeller import _find_module_containing_node
-from gump.engine.modeller import _do_drop
-
-###
-### Helper methods
-###
-def _resolve_hrefs_in_children(element, dropped_nodes, found_hrefs, download_func, error_func):
-    """Recursively resolve all hrefs in all the children for a DOM node.
-    
-    The resolution is done in a resolve-then-recurse manner, so the end
-    result is a dom tree without hrefs. Note that this method expects to
-    be passed in a dom Element or something else which actually has children;
-    passing in an Attr for example makes no sense and results in problems.
-    
-    The dropped_nodes argument should be a list that will be populated with
-    nodes for which href resolution fails.
-    
-    The found_hrefs argument should be a list that will be populated with all
-    the hrefs that have been resolved by the method that resolved hrefs for
-    the parent. An error will be thrown when recursion is detected.
-    """
-    for child in element.childNodes:
-        # only resolve hrefs for elements
-        if not child.nodeType == dom.Node.ELEMENT_NODE: continue
-        # there's a <url href=""/> element which is descriptive and should
-        # not be resolved
-        if child.tagName == 'url': continue
-        if child.hasAttribute('href'):
-            # yep, this is one to load...
-            _resolve_href(child, dropped_nodes, found_hrefs, download_func, error_func)
-
-        # now recurse to resolve any hrefs within this child
-        # note that we duplicate the found_hrefs array. This means that the
-        # same file can be imported multiple times, as long as it is imported
-        # by siblings, rather than as part of some parent<->child relation.
-        _resolve_hrefs_in_children(child, dropped_nodes, found_hrefs[:], download_func, error_func)
-
-def _resolve_href(node, dropped_nodes, found_hrefs, download_func, error_func):
-    """Resolve a href for the provided node.
-
-    We merge in the referenced xml document into the provided node.
-    The href attribute on the provided node will be removed if the merge
-    succeeds. If the merge fails the provided node will be removed from
-    its parent and appended to the dropped_nodes list.
-    """
-    href = node.getAttribute('href')
-    if href in found_hrefs:
-        raise EngineError, \
-              """Recursive inclusion because files refer to each other. This href leads to
-              a cycle: %s.""" % href
-    found_hrefs.append(href)
-    
-    try:
-        stream = download_func(href)
-    except Exception, details:
-        # swallow this in interest of log readability
-        #_drop_module_or_project(node, dropped_nodes)
-        error_func(href, node, dropped_nodes)
-        return # make sure to stop processing...
-    
-    new_dom = minidom.parse(stream)
-    new_dom.normalize()
-    stream.close() # close file immediately, we're done!
-    new_root = new_dom.documentElement
-    
-    # we succeeded loading the new document, get rid of the href, save it
-    # as "resolved"
-    node.removeAttribute('href')
-    node.setAttribute('resolved-from-href', href)
-    
-    _import_node(node, new_root)
-    
-    # we're done with the file now, allow GC
-    new_root.unlink()
-
-###
-### Classes
-###
-class Loader:
-    """Parses and resolves Gump XML metadata.
-
-    The only "public" method of this class is get_workspace_tree. This method
-    reads in a gump workspace. It then looks for any elements in that workspace
-    that have a "href" attribute. This href attribute is resolved to a new XML
-    file using the provided Virtual File System, which is then merged with the
-    Element that has the attribute. That resolution process is continued until
-    the entire workspace no longer contains any hrefs. At that point, the entire
-    Workspace is returned as a DOM Element.
-
-    If any HREFs fail to resolve properly, the associated projects (or if there
-    are no associated projects, the associated modules) are removed from the
-    workspace completely. If no associated project or module exists, the Loader
-    will give up and raise an exception.
-    
-    Note that the loader does *not* do any verification of the XML it loads.
-    The only thing it assumes is the existence of <project/> elements contained
-    within <module/> elements, and that these elements have name attributes. So,
-    for example, the following would be parsed without complaints by the loader:
-        
-        <bogus>
-          <imagine>
-            <any>
-              <xml-data>
-                <with>
-                  <module name="foo">
-                    <project name="bar">
-                      <build href="somefile.xml"/>
-                    </project>
-                    <project href="otherfile.xml"/>
-                  </module>
-                  <module href="jo.xml"/>
-                </with>
-              </xml-data>
-        </bogus>
-    
-    Of course, other parts of the modeller package are not so tolerant!
-    """
-    def __init__(self, log, vfs=None):
-        """
-        Create a new Loader.
-
-        Arguments:
-            
-            - log -- the log to write debug and error messages to.
-            - vfs -- the virtual file system to use for resolving hrefs. May
-                     be None only if the workspace to load does not contain
-                     any hrefs.
-        """
-        assert hasattr(log, "warning")
-        assert callable(log.warning)
-        if vfs:
-            assert hasattr(vfs, "get_as_stream")
-            assert callable(vfs.get_as_stream)
-        self.log = log
-        self.vfs = vfs
-    
-    def get_workspace_tree(self, workspace):
-        """Parse the provided workspace, then resolve all hrefs.
-        
-        Returns a tuple with the parsed workspace as a dom Element, and all
-        the Nodes that were dropped because of problems as a list.
-        """
-        # get root <workspace/> element
-        wsdom = minidom.parse(workspace)
-        wsdom.normalize()
-        ws = wsdom.documentElement
-        
-        dropped_nodes = [] # will be used for storing projects we drop...
-        
-        # resolve all hrefs in all elements, for example
-        # <project href="blah.xml"/>; replaces that element with the
-        # contents of blah.xml
-        _resolve_hrefs_in_children(ws, dropped_nodes, [], self.get_as_stream, self.handle_error)
-        
-        # the combined results
-        return (wsdom, dropped_nodes)
-    
-    # callback interface for _resolve_hrefs_in_workspace
-    def get_as_stream(self, href):
-        self.log.debug( "Resolving HREF: %s" % href )
-        return self.vfs.get_as_stream(href)
-
-    def handle_error(self, href, node, dropped_nodes):
-        """Finds the project associated with this node and removes it.
-        
-        If there is no associated project, the associated module is removed
-        instead. If there is no module either, an exception is raised.
-        """
-        
-        project = _find_project_containing_node(node)
-        if project:
-            doc = _find_document_containing_node(project)
-            modulename = "Uknown"
-            module = _find_module_containing_node(project)
-            if module:
-                modulename = module.getAttribute("name")
-                comment = doc.createComment(" Part of module: %s " % modulename)
-                project.appendChild(comment)
-            name = project.getAttribute("name")
-            if not name:
-                name = "Uknown"
-            self.log.warning("Dropping project '%s' from module '%s' because of href (%s) resolution error!" % (name , modulename, href))
-    
-            _do_drop(project, dropped_nodes)
-        else:
-            module = _find_module_containing_node(node)
-            if module:
-                doc = _find_document_containing_node(module)
-                name = module.getAttribute("name")
-                self.log.warning("Dropping module '%s' because of href resolution error!" % name)
-    
-                _do_drop(project, dropped_nodes)
-            else:
-                raise EngineError, \
-                      "Problematic node has no parent <project/> or " + \
-                      "<module/>, unable to recover! Node:\n%s" \
-                      % node.toprettyxml()
+def has_previous_build(project):
+    """Determine if information from a previous build was stored for this project."""
+    return hasattr(project, "previous_build")
+
+
+def store_previous_build(project):
+    import copy
+    
+    stored_project = copy.deepcopy(project) # TODO problem here!!!!
+    
+    if getattr(project, "failed", False):
+        return
+    
+    for output in project.outputs:
+        if isinstance(output, Homedir):
+            store_previous_build_homedir(project, output)
+            continue
+        if isinstance(output, Jar):
+            store_previous_build_jar(project, output)
+            continue
+        
+        raise "Can't store this kind of output (%s)!" % output
+
+# TODO make module out of all this, make this configurable
+import shutil
+storage_dir = os.path.join("work", "previous_build_storage")
+if not os.path.exists(storage_dir):
+  os.makedirs(storage_dir)
+
+def store_previous_build_homedir(project, homedir):
+    homedir_path = os.path.join(get_project_directory(project), homedir.directory)
+    homedir_storage_path = os.path.join(storage_dir, homedir_path)
+    shutil.copytree(homedir_path, homedir_storage_path)
+
+def is_special_previous_build_attr(name):
+    return name == "delete_atts_when_stopping_to_use_previous_build" or \
+           name == "use_atts_when_stopping_to_use_previous_build" or \
+           name == "previous_build"
+
+def use_previous_build(project):
+    # if the "previous build" "failed" we'll not attempt to use it
+    if getattr(project.previous_build, "failed", False):
+        return
+    
+    if hasattr(project, "use_atts_when_stopping_to_use_previous_build"):
+        # use_previous_build() seemingly was already active on this build
+        return
+
+    # we'll replace all current members with the "old" members
+    import inspect
+    members = inspect.getmembers(project)
+    oldmembers = inspect.getmembers(project.previous_build)
+    
+    # remember...
+    project.use_atts_when_stopping_to_use_previous_build = members
+
+    # we'll delete all current members that weren't there before
+    temporarily_delete_attrs = []
+    for (newname, newvalue) in members:
+        found_in_old = False
+        for (oldname, oldvalue) in oldmembers:
+            if oldname == newname:
+                found_in_old = True
+                break
+        
+        if not found_in_old and not is_special_previous_build_attr(attname):
+            delattr(project, attname)
+    
+    # we'll have to remove the members on the old project but not
+    # on the new one
+    temporarily_add_attrs = []
+    for (oldname, oldvalue) in oldmembers:
+        found_in_new = False
+        for (newname, newvalue) in newmembers:
+            if newname == oldname:
+                found_in_new = True
+                break
+        
+        if not found_in_new and not is_special_previous_build_attr(attname):
+            temporarily_add_attrs += oldname
+    
+    # the "failed" member is a special case since we set it below
+    if not hasattr(project, "failed"):
+        temporarily_add_attrs += "failed"
+    
+    # remember...
+    project.delete_atts_when_stopping_to_use_previous_build = temporarily_add_attrs
+
+    # move all old project members to the new one
+    for (name, value) in oldmembers:
+        if is_special_previous_build_attr(name):
+            continue
+        setattr(project, name, value)
+        
+    # unmark failure as a sanity check (we checked for it above)
+    project.failed = False
+    
+    
+def stop_using_previous_build(project):
+    if not hasattr(project, "use_atts_when_stopping_to_use_previous_build"):
+        # use_previous_build() seemingly wasn't active on this build
+        return
+    
+    # these were the temporary ones
+    attlist = project.delete_atts_when_stopping_to_use_previous_build
+    for attname in attlist:
+        if is_special_previous_build_attr(name):
+            # safety. This won't happen if use_previous_build() is used
+            continue
+        delattr(project, attname)
+    
+    # these were the actual values
+    for (name,value) in project.use_atts_when_stopping_to_use_previous_build:
+        if is_special_previous_build_attr(name):
+            # safety. This won't happen if use_previous_build() is used
+            continue
+        setattr(project, name, value)
+    
+    # get rid of the remembered stuff
+    if hasattr(project, "delete_atts_when_stopping_to_use_previous_build"):
+        del project.delete_atts_when_stopping_to_use_previous_build
+    if hasattr(project, "use_atts_when_stopping_to_use_previous_build"):
+        del project.use_atts_when_stopping_to_use_previous_build

Modified: gump/branches/Gump3/pygump/python/gump/engine/walker.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/engine/walker.py?rev=209079&r1=209078&r2=209079&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/engine/walker.py (original)
+++ gump/branches/Gump3/pygump/python/gump/engine/walker.py Mon Jul  4 06:54:27 2005
@@ -75,7 +75,7 @@
             visited_projects.append(project)
         
         self.log.debug('Visitor %s finalize, on %s walk.' % (`visitor`, description))
-        visitor._finalize()
+        visitor._finalize(workspace)
         return (visited_repositories, visited_modules, visited_projects)
     
     def _topsort_projects(self, workspace):

Modified: gump/branches/Gump3/pygump/python/gump/model/__init__.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/model/__init__.py?rev=209079&r1=209078&r2=209079&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/model/__init__.py (original)
+++ gump/branches/Gump3/pygump/python/gump/model/__init__.py Mon Jul  4 06:54:27 2005
@@ -36,6 +36,21 @@
             return "<%s>" % typerep
 
 
+class ExceptionInfo(ModelObject):
+    """Model an exception.
+
+    Basically we're saving an exception tuple (ie what is
+    returned by sys.exc_info()) inside something that's also
+    a "ModelObject"."""
+    def __init__(self, type, value, traceback):
+        self.type = type
+        self.value = value
+        self.traceback = traceback
+    
+    def __str__(self):
+        return "<%s:%s>" % (self.type, self.value)
+
+
 class Workspace(ModelObject):
     """Model gump workspace and profile.
 

Modified: gump/branches/Gump3/pygump/python/gump/model/util.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/model/util.py?rev=209079&r1=209078&r2=209079&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/model/util.py (original)
+++ gump/branches/Gump3/pygump/python/gump/model/util.py Mon Jul  4 06:54:27 2005
@@ -147,3 +147,13 @@
             lines = log.split('\n')
             if len(lines) > 1:
                 module.was_updated = True
+
+def check_module_update_failure(module):
+    """Determine whether a module "update" "failed"."""
+    return getattr(module, "update_exit_status", False)
+
+def store_exception(model_element, type, value, traceback):
+    """Save exception information with a model element."""
+    if not hasattr(model_object, 'exceptions'):
+        model_object.exceptions = []
+    model_object.exceptions.append(ExceptionInfo(type, value, traceback))

Modified: gump/branches/Gump3/pygump/python/gump/plugins/__init__.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/plugins/__init__.py?rev=209079&r1=209078&r2=209079&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/plugins/__init__.py (original)
+++ gump/branches/Gump3/pygump/python/gump/plugins/__init__.py Mon Jul  4 06:54:27 2005
@@ -116,10 +116,10 @@
         if not callable(self.visit_project): return        
         self.visit_project(project)
 
-    def _finalize(self):
+    def _finalize(self, workspace):
         if not hasattr(self,'finalize'): return        
         if not callable(self.finalize): return        
-        self.finalize()
+        self.finalize(workspace)
     
     def __str__(self):
         return self.__class__.__name__
@@ -144,6 +144,6 @@
     def visit_project(self, project):
         self.log.debug("Visiting project '%s'." % project.name)
 
-    def finalize(self):
+    def finalize(self, workspace):
         self.log.debug("Finishing up...")
     

Modified: gump/branches/Gump3/pygump/python/gump/plugins/logreporter.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/plugins/logreporter.py?rev=209079&r1=209078&r2=209079&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/plugins/logreporter.py (original)
+++ gump/branches/Gump3/pygump/python/gump/plugins/logreporter.py Mon Jul  4 06:54:27 2005
@@ -90,7 +90,7 @@
         for command in project.commands:
             self._do_log_printing_visit(command,project)
             
-    def finalize(self):
+    def finalize(self, workspace):
         self.log.debug('  Finished outputting all log data.')
         self.log.debug('-----------------------------------')
 
@@ -220,7 +220,7 @@
                         
                     indent += "  "
                     
-    def finalize(self):
+    def finalize(self, workspace):
         self.wr('  ==========================================================================')
         
         self.buffer.flush()

Modified: gump/branches/Gump3/pygump/python/gump/test/testDynagumper.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/test/testDynagumper.py?rev=209079&r1=209078&r2=209079&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/test/testDynagumper.py (original)
+++ gump/branches/Gump3/pygump/python/gump/test/testDynagumper.py Mon Jul  4 06:54:27 2005
@@ -46,19 +46,40 @@
 
     def test_visit_workspace(self):
         #TODO
-        dynagumper = Dynagumper(self.db,self.log)
-        dynagumper.visit_workspace("blah")
+        class w:
+          def __init__(self, n, d):
+            self.name = n
+            self.description = d
+            
+        wi = w("blah", "blah blah")
+        db = self.mock()
+        db.expects(once()).method("execute").will(raise_exception(RuntimeError('bla')))
+        dynagumper = Dynagumper(db,self.log)
+        self.assertRaises(RuntimeError, dynagumper.visit_workspace, wi)
     
     def test_visit_module(self):
         #TODO
+        class m:
+          def __init__(self, n, d, u):
+            self.name = n
+            self.description = d
+            self.url = u
+            
+        mi = m("blah", "blah blah", "http://example.com")
         dynagumper = Dynagumper(self.db,self.log)
-        dynagumper.visit_module("blah")
+        db = self.mock()
+        db.expects(once()).method("execute").will(raise_exception(RuntimeError('bla')))
+        dynagumper = Dynagumper(db,self.log)
+        self.assertRaises(RuntimeError, dynagumper.visit_module, mi)
     
     def test_visit_project(self):
         #TODO
-        dynagumper = Dynagumper(self.db,self.log)
+        db = self.mock()
+        db.expects(once()).method("execute").will(raise_exception(RuntimeError('bla')))
+        dynagumper = Dynagumper(db,self.log)
         self.project = self.mock()
         self.project.name = "blah"
         self.project.startdate = "21 June 2005"
         self.project.enddate = "22 June 2005"
-        dynagumper.visit_project(self.project)
+        
+        self.assertRaises(RuntimeError, dynagumper.visit_project, self.project)

Modified: gump/branches/Gump3/pygump/python/gump/test/testUtilIO.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/test/testUtilIO.py?rev=209079&r1=209078&r2=209079&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/test/testUtilIO.py (original)
+++ gump/branches/Gump3/pygump/python/gump/test/testUtilIO.py Mon Jul  4 06:54:27 2005
@@ -124,7 +124,6 @@
 The testcase for the VFS utility needs a live internet connection. It seems
 that is currently not available. This is likely a non-critical problem.
 """
-            raise
         
         try:
             os.rmdir(base)

Modified: gump/branches/Gump3/pygump/python/gump/test/testUtilMysql.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/test/testUtilMysql.py?rev=209079&r1=209078&r2=209079&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/test/testUtilMysql.py (original)
+++ gump/branches/Gump3/pygump/python/gump/test/testUtilMysql.py Mon Jul  4 06:54:27 2005
@@ -54,26 +54,7 @@
         d.rollback()
         
         try:
-            c = d.cursor()
-            self.assertNotEqual(None, c)
-            c = None
-            (rows, result) = d.execute("DROP TABLE IF EXISTS gump_unit_test;")
-            self.assertEqual(0, rows)
-            
-            (rows, result) = d.execute("CREATE TABLE gump_unit_test (id INT);")
-            self.assertEqual(0, rows)
-            self.assertEqual(None, result)
-            
-            (rows, result) = d.execute("INSERT INTO gump_unit_test (id) VALUES (10);")
-            self.assertEqual(1, rows)
-            self.assertEqual(None, result)
-            
-            (rows, result) = d.execute("SELECT * FROM gump_unit_test;")
-            self.assertEqual(1, rows)
-            self.assertEqual(10, result[0]["id"])
-            
-            (rows, result) = d.execute("DROP TABLE gump_unit_test;")
-            self.assertEqual(0, rows)
+            (rows, result) = d.execute("SHOW TABLES;")
         except Exception:
             if not os.environ.has_key("GUMP_TEST_NO_MYSQL"):
                 print """
@@ -84,5 +65,25 @@
   GUMP_TEST_NO_MYSQL
 prior to running this test.
 """
-                raise
+            return
 
+        c = d.cursor()
+        self.assertNotEqual(None, c)
+        c = None
+        (rows, result) = d.execute("DROP TABLE IF EXISTS gump_unit_test;")
+        self.assertEqual(0, rows)
+        
+        (rows, result) = d.execute("CREATE TABLE gump_unit_test (id INT);")
+        self.assertEqual(0, rows)
+        self.assertEqual(None, result)
+        
+        (rows, result) = d.execute("INSERT INTO gump_unit_test (id) VALUES (10);")
+        self.assertEqual(1, rows)
+        self.assertEqual(None, result)
+        
+        (rows, result) = d.execute("SELECT * FROM gump_unit_test;")
+        self.assertEqual(1, rows)
+        self.assertEqual(10, result[0]["id"])
+        
+        (rows, result) = d.execute("DROP TABLE gump_unit_test;")
+        self.assertEqual(0, rows)

Modified: gump/branches/Gump3/pygump/python/gump/util/sysinfo.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/util/sysinfo.py?rev=209079&r1=209078&r2=209079&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/util/sysinfo.py (original)
+++ gump/branches/Gump3/pygump/python/gump/util/sysinfo.py Mon Jul  4 06:54:27 2005
@@ -27,7 +27,7 @@
 def amount_of_memory():
     """Returning an integer giving the amount of RAM memory in the system,
     in megabytes. Returns 0 if the amount of RAM cannot be determined."""
-    if sys.platform == "win32":
+    if sys.platform != "linux":
         return 0
     amount = 0 # i.e., we don't know
     cat = Popen(["cat", "/proc/meminfo"], stdout=PIPE)
@@ -45,7 +45,7 @@
 def amount_of_cpu_mhz():
     """Returning an integer giving the processor speed for this system,
     in MHz. Returns 0 if the processor speed cannot be determined."""
-    if sys.platform == "win32":
+    if sys.platform != "linux":
         return 0
     amount = 0 # i.e., we don't know
     cat = Popen(["cat", "/proc/cpuinfo"], stdout=PIPE)
@@ -66,7 +66,7 @@
 def number_of_cpus():
     """Returning an integer giving the number of CPUs in the system.
     Returns 0 if the number of CPUs cannot be determined."""
-    if sys.platform == "win32":
+    if sys.platform != "linux":
         return 0
     amount = 0 # i.e., we don't know
     cat = Popen(["cat", "/proc/cpuinfo"], stdout=PIPE)

Copied: gump/branches/Gump3/pygump/python/main.py (from r202450, gump/branches/Gump3/pygump/main.py)
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/main.py?p2=gump/branches/Gump3/pygump/python/main.py&p1=gump/branches/Gump3/pygump/main.py&r1=202450&r2=209079&rev=209079&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/main.py (original)
+++ gump/branches/Gump3/pygump/python/main.py Mon Jul  4 06:54:27 2005
@@ -454,7 +454,7 @@
             log.debug("No projects to build set, defaulting to 'all'")
             options.projects = ["all"]
         if not os.path.exists(options.workspace):
-            log.error("Workspace not found : %s." % options.workspace)
+            log.error("Workspace not found : %s.\n       Maybe you need to specify --workspace=/absolute/path/to/some/workspace/file.xml?" % options.workspace)
             sys.exit(1)
         
         # get some more options from the workspace