gump-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From leosim...@apache.org
Subject svn commit: r210128 - in /gump/branches/Gump3: ./ metadata/ pygump/python/ pygump/python/gump/ pygump/python/gump/engine/ pygump/python/gump/model/ pygump/python/gump/plugins/ pygump/python/gump/plugins/java/ pygump/python/gump/test/ pygump/python/gump...
Date Mon, 11 Jul 2005 13:41:39 GMT
Author: leosimons
Date: Mon Jul 11 06:41:39 2005
New Revision: 210128

URL: http://svn.apache.org/viewcvs?rev=210128&view=rev
Log:
 * implement support for partial runs
 
 * implement support for customizing the local repository location
 
 * use multiple process groups
 
 * provide option to disable process group management
 
 * disable process group management for running ant. See inside
   gump.plugins.java.builder.AntPlugin for some details. This was a *huge*
   pain to figure out. What triggered this is the invocation of java_cup
   from the xalan build.xml file, which has a <java fork="true".
 
 * use jdk 1.5 on my machine
 
 * add some implementation notes
 
 * start implement parsing out of @@VARIABLE@@s using a new piece of
   engine

 * add more basic packages to the vmgump.xml file
 
 * on my machine at least, we now successfully build all the way up to xalan :-)

Added:
    gump/branches/Gump3/pygump/python/gump/engine/at_parser.py
      - copied, changed from r210019, gump/branches/Gump3/pygump/python/gump/engine/verifier.py
Modified:
    gump/branches/Gump3/giraffe-settings.sh
    gump/branches/Gump3/metadata/vmgump.xml
    gump/branches/Gump3/pygump/python/gump/config.py
    gump/branches/Gump3/pygump/python/gump/engine/__init__.py
    gump/branches/Gump3/pygump/python/gump/engine/algorithm.py
    gump/branches/Gump3/pygump/python/gump/model/__init__.py
    gump/branches/Gump3/pygump/python/gump/plugins/builder.py
    gump/branches/Gump3/pygump/python/gump/plugins/java/builder.py
    gump/branches/Gump3/pygump/python/gump/test/testConfig.py
    gump/branches/Gump3/pygump/python/gump/util/executor.py
    gump/branches/Gump3/pygump/python/main.py

Modified: gump/branches/Gump3/giraffe-settings.sh
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/giraffe-settings.sh?rev=210128&r1=210127&r2=210128&view=diff
==============================================================================
--- gump/branches/Gump3/giraffe-settings.sh (original)
+++ gump/branches/Gump3/giraffe-settings.sh Mon Jul 11 06:41:39 2005
@@ -6,6 +6,6 @@
 if [[ "$cygwin" == "true" ]]; then
   export JAVA_HOME=/cygdrive/c/j2sdk1.4.2_08
 else
-  export JAVA_HOME=/usr/lib/j2se/1.4
+  export JAVA_HOME=/usr/lib/j2se/1.5
 fi
 

Modified: gump/branches/Gump3/metadata/vmgump.xml
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/metadata/vmgump.xml?rev=210128&r1=210127&r2=210128&view=diff
==============================================================================
--- gump/branches/Gump3/metadata/vmgump.xml (original)
+++ gump/branches/Gump3/metadata/vmgump.xml Mon Jul 11 06:41:39 2005
@@ -34,7 +34,6 @@
     <repository name="gump" type="svn">
         <title>Gump</title>
         <home-page>http://gump.apache.org/</home-page>
-        <web>http://cvs.apache.org/viewcvs.cgi/gump/?root=Apache-SVN</web>
         <url>http://svn.apache.org/repos/asf/gump/branches/Gump3</url>
         <redistributable/>
     </repository>
@@ -51,6 +50,14 @@
         <user>anoncvs</user>
         <password>anoncvs</password>
     </repository>
+
+    <repository name="jakarta-svn" type="svn">
+        <title>Apache Jakarta</title>
+        <home-page>http://jakarta.apache.org</home-page>
+        <cvsweb>http://cvs.apache.org/viewcvs.cgi/jakarta/?root=Apache-SVN</cvsweb>
+        <url>http://svn.apache.org/repos/asf/jakarta</url>
+        <redistributable/>
+    </repository>
 </repositories>
     
 <modules>
@@ -96,6 +103,20 @@
         <description>Release 2.x of the Xalan-Java XSLT processor</description>
 
     </module>
+
+    <module name="jakarta-bcel" path="bcel/trunk">
+        <repository name="jakarta-svn"/>
+
+        <url href="http://jakarta.apache.org/bcel"/>
+        <description>Byte Code Engineering Library</description>
+    </module>
+
+    <module name="jakarta-regexp" path="regexp/trunk">
+        <repository name="jakarta-svn"/>
+
+        <url href="http://jakarta.apache.org/regexp/index.html"/>
+        <description>Java Regular Expression package</description>
+    </module>
 </modules>
 
 <projects>
@@ -160,17 +181,13 @@
         <jar name="which.jar" id="which"/>
         
         <!-- dependencies -->
+        <depend project="xml-apis"/>
         <depend project="xml-xerces"/>
         <depend project="bootstrap-ant"/>
     </project>
 
     <project name="xml-commons-resolver">
         <module name="xml-commons"/>
-        <depend project="xml-resolver" inherit="jars"/>
-    </project>
-
-    <project name="xml-resolver">
-        <module name="xml-commons"/>
 
         <!-- commands -->
         <ant basedir="java" buildfile="resolver.xml" target="gump"/>
@@ -185,8 +202,14 @@
         <depend project="bootstrap-ant" inherit="runtime"/>
     </project>
     
-    <project name="jaxp">
-        <!-- assumed to be provided by JDK -->
+    <project name="jaxp" path="jaxp-1_3-20050622-gump-20050710">
+        <!-- installed package -->
+        <!-- outputs -->
+        <jar name="jaxp-api.jar" id="jaxp-api" type="boot"/>
+        <jar name="dom.jar" id="dom" type="boot"/>
+        <jar name="sax.jar" id="sax" type="boot"/>
+        <jar name="xercesImpl.jar" id="xml-parser" type="boot"/>
+        <jar name="xalan.jar" id="xalan" type="boot"/>
     </project>
 
     <project name="xml-xerces">
@@ -203,18 +226,6 @@
         <depend project="bootstrap-ant"/>
         <depend project="xjavac"/>
         <depend project="xml-commons-resolver"/>
-        <option project="jaxp" ids="jaxp-api dom sax"/>
-    </project>
-    
-    <project name="xml-xercesImpl">
-        <module name="xml-xerces"/>
-
-        <!-- outputs -->
-        <home nested="java/build"/>
-        <jar name="xercesImpl.jar" id="xercesImpl"/>
-
-        <!-- dependencies -->
-        <depend project="xml-xerces"/>
     </project>
     
     <project name="xjavac">
@@ -226,7 +237,7 @@
     </project>
 
     <project name="xalan">
-        <module name="xml"/>
+        <module name="xml-xalan"/>
         
         <!-- commands -->
         <ant basedir="java" target="unbundledjar">
@@ -252,6 +263,8 @@
     </project>
 
     <project name="xsltc">
+        <module name="xml-xalan"/>
+        
         <!-- commands -->
         <ant basedir="java" target="xsltc.unbundledjar"/>
 
@@ -272,6 +285,8 @@
     </project>
 
     <project name="java_cup">
+        <module name="xml-xalan"/>
+        
         <!-- outputs -->
         <home nested="java"/>
         <jar name="bin/java_cup.jar"/>
@@ -279,9 +294,47 @@
     </project>
 
     <project name="jlex">
+        <module name="xml-xalan"/>
+        
         <!-- outputs -->
         <home nested="java"/>
         <jar name="bin/JLex.jar"/>
     </project>
+    
+    <project name="bcel">
+        <module name="jakarta-bcel"/>
+        
+        <!-- commands -->
+        <ant/>
+
+        <!-- outputs -->
+        <jar name="bin/bcel.jar"/>
+
+        <!-- dependencies -->
+        <depend project="bootstrap-ant" inherit="runtime"/>
+        <depend project="xml-apis"/>
+        <depend project="xml-xerces"/>
+        <depend project="jakarta-regexp" runtime="true"/>
+    </project>
+
+    <project name="jakarta-regexp">
+        <module name="jakarta-regexp"/>
+        
+        <!-- commands -->
+        <ant target="jar">
+            <!-- TODO <property name="version" value="@@DATE@@"/>-->
+        </ant>
+        
+        <!-- ouputs -->
+        <home nested="build"/>
+        <!-- TODO <jar name="jakarta-regexp-@@DATE@@.jar" id="regexp"/>-->
+        <jar name="jakarta-regexp-1.4-dev.jar" id="regexp"/>
+        
+        <!-- dependencies -->
+        <depend project="bootstrap-ant" inherit="runtime"/>
+        <depend project="xml-apis"/>
+        <depend project="xml-xerces"/>
+  </project>
+
 </projects>
-</workspace>
\ No newline at end of file
+</workspace>

Modified: gump/branches/Gump3/pygump/python/gump/config.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/config.py?rev=210128&r1=210127&r2=210128&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/config.py (original)
+++ gump/branches/Gump3/pygump/python/gump/config.py Mon Jul 11 06:41:39 2005
@@ -120,6 +120,7 @@
         plugins.append(ClasspathPlugin(buildlog,Ant))
         from gump.plugins.java.builder import AntPlugin
         plugins.append(AntPlugin(buildlog))
+        #plugins.append(AntPlugin(buildlog, debug=True))
     else:
         log.info("Not running builds! (pass --do-builds to enable them)")
      
@@ -189,6 +190,16 @@
     log = get_logger(config, "plugin.error-handler")
     return OptimisticLoggingErrorHandler(log)
 
+
+def get_at_variable_dictionary(config):
+    import time
+    
+    dictionary = {}
+    dictionary["GUMP_VERSION"] = config.version
+    dictionary["DATE"] = time.strftime("%Y%m%d%h%M")
+    
+    return dictionary
+
 ###
 ### Changing anything below this line is for advanced gump hackers only!
 ###
@@ -268,6 +279,13 @@
     return Normalizer(log)
 
 
+def get_engine_at_parser(config):
+    """Provide a AtParser implementation."""
+    from gump.engine.at_parser import AtParser
+    
+    return AtParser(get_at_variable_dictionary(config))
+
+
 def get_engine_objectifier(config, log):
     """Provide a Objectifier implementation."""
     from gump.engine.objectifier import Objectifier
@@ -304,9 +322,13 @@
     (pre_process_plugins, plugins, post_process_plugins) = get_plugins(config)
     error_handler = get_error_handler(config)
     
+    if getattr(config, "project_name", False):
+        mainalgorithm = MoreEfficientAlgorithm(plugins, error_handler, project_list=config.project_name)
+    else:
+        mainalgorithm = MoreEfficientAlgorithm(plugins, error_handler)
+    
     return (DumbAlgorithm(pre_process_plugins, error_handler),
-            MoreEfficientAlgorithm(plugins, error_handler),
-            #DumbAlgorithm(plugins, error_handler),
+            mainalgorithm, #DumbAlgorithm(plugins, error_handler)
             DumbAlgorithm(post_process_plugins, error_handler))
 
 #
@@ -330,3 +352,11 @@
     # this will make Popen log all invocations
     import gump.util.executor
     gump.util.executor._log = get_logger(config, "util.executor")
+    
+    # set up gump.engine.objectifier module
+    # this will change where we look for installed packages
+    import gump.engine.objectifier
+    if config.local_repository_name:
+        gump.engine.objectifier.DEFAULT_GUMP_LOCAL_REPOSITORY_NAME = config.local_repository_name
+    if config.local_module_name:
+        gump.engine.objectifier.DEFAULT_GUMP_LOCAL_MODULE_NAME = config.local_module_name

Modified: gump/branches/Gump3/pygump/python/gump/engine/__init__.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/engine/__init__.py?rev=210128&r1=210127&r2=210128&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/engine/__init__.py (original)
+++ gump/branches/Gump3/pygump/python/gump/engine/__init__.py Mon Jul 11 06:41:39 2005
@@ -49,6 +49,7 @@
 from gump.config import get_engine_walker
 from gump.config import get_engine_loader
 from gump.config import get_engine_normalizer
+from gump.config import get_engine_at_parser
 from gump.config import get_engine_objectifier
 from gump.config import get_engine_verifier
 from gump.config import get_dom_implementation
@@ -108,6 +109,7 @@
     engine_log = get_logger(config, _ENGINE_HELPER_LOGGER_NAME)
     engine_loader = get_engine_loader(engine_log, vfs)
     engine_normalizer = get_engine_normalizer(engine_log)
+    engine_at_parser = get_engine_at_parser(config)
     engine_objectifier = get_engine_objectifier(config, engine_log)
     engine_verifier = get_engine_verifier(config, engine_walker)
     
@@ -118,7 +120,7 @@
     (pre_process_visitor, visitor, post_process_visitor) = get_plugin(config)
     
     # create engine
-    engine = _Engine(log, engine_loader, engine_normalizer,
+    engine = _Engine(log, engine_loader, engine_normalizer, engine_at_parser,
                      engine_objectifier, engine_verifier, engine_walker,
                      dom_implementation,
                      pre_process_visitor, visitor, post_process_visitor,
@@ -222,6 +224,7 @@
     xml into an object model and let loose plugins on that model."""
     
     def __init__(self, log, workspace_loader, workspace_normalizer,
+                 workspace_at_parser,
                  workspace_objectifier, workspace_verifier, walker,
                  dom_implementation,
                  pre_process_visitor, visitor, post_process_visitor,
@@ -234,6 +237,8 @@
             - workspace_loader -- the component providing the dom tree.
             - workspace_normalizer -- the component transforming the dom tree
                 into a standard format
+            - workspace_at_parser -- the component transforming the dom tree
+                replacing all the '@@VARIABLE@@' strings
             - workspace_objectifier -- the component transforming the dom into
                 object form
             - workspace_verifier -- the component making sure the object model
@@ -261,6 +266,8 @@
         assert callable(workspace_loader.get_workspace_tree)
         assert hasattr(workspace_normalizer, "normalize")
         assert callable(workspace_normalizer.normalize)
+        assert hasattr(workspace_at_parser, "parse")
+        assert callable(workspace_at_parser.parse)
         assert hasattr(workspace_objectifier, "get_workspace")
         assert callable(workspace_objectifier.get_workspace)
         assert hasattr(workspace_verifier, "verify")
@@ -274,6 +281,7 @@
         self.log = log
         self.workspace_loader = workspace_loader
         self.workspace_normalizer = workspace_normalizer
+        self.workspace_at_parser = workspace_at_parser
         self.workspace_objectifier = workspace_objectifier
         self.workspace_verifier = workspace_verifier
         self.walker = walker
@@ -297,6 +305,9 @@
             
             # * clean it up and structure it properly
             domtree = self.workspace_normalizer.normalize(domtree)
+            
+            # * replace @@VARIABLE@@ sequences
+            domtree = self.workspace_at_parser.parse(domtree)
             
             # * write the merged, normalized tree out to a new xml file
             self._write_merge_files(domtree, dropped_nodes)

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=210128&r1=210127&r2=210128&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/engine/algorithm.py (original)
+++ gump/branches/Gump3/pygump/python/gump/engine/algorithm.py Mon Jul 11 06:41:39 2005
@@ -33,6 +33,7 @@
 __license__   = "http://www.apache.org/licenses/LICENSE-2.0"
 
 import sys
+import re
 
 from gump.util import ansicolor
 from gump.model import ModelObject, CvsModule, ExceptionInfo, Jar
@@ -172,6 +173,10 @@
     def stop_using_previous_build(self, arg):
         pass
 
+DEFAULT_PROJECT_REGEX = ".*"
+DEFAULT_PROJECT_LIST = []
+DEFAULT_PROJECT_LIST.append(DEFAULT_PROJECT_REGEX)
+
 class MoreEfficientAlgorithm(DumbAlgorithm):
     """Algorithm that implements a more efficient build algorithm.
 
@@ -188,19 +193,43 @@
     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()):
+    def __init__(self, plugin_list, error_handler=BaseErrorHandler(),
+                 persistence_helper=NoopPersistenceHelper(), project_list=DEFAULT_PROJECT_LIST):
         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
+        assert hasattr(persistence_helper, "use_previous_build")
+        assert callable(persistence_helper.use_previous_build)
+        self.persistence_helper = persistence_helper
+          
+        assert isinstance(project_list, list)
+        for p in project_list:
+            assert isinstance(p, basestring)
+
+        self.project_list = project_list
+        self.project_match_list = [re.compile(p) for p in project_list]
+        self.project_model_list = []
+        self.module_model_list = []
+        
+    def _visit_workspace(self, workspace):
+        for k,v in workspace.projects.iteritems():
+            for x in self.project_match_list:
+                if x.match(k):
+                    self.project_model_list.append(v)
+                    break
+        
+        for p in self.project_model_list:
+            if not p.module in self.module_model_list:
+                self.module_model_list.append(p.module)
         
     def _visit_module(self, module):
         # DEBUG TIP: This is a good function to monitor if you want to figure
         #   out flow control
         # run the delegates
         try:
+            if not module in self.module_model_list:
+                mark_skip(module)
+                return
+            
             for visitor in self.list:
                 visitor._visit_module(module)
         except:
@@ -227,6 +256,11 @@
         # DEBUG TIP: This is a good function to monitor if you want to figure
         #   out flow control
         # check for dependencies that failed to build
+        
+        if not project in self.project_model_list:
+            mark_skip(project)
+            return
+        
         for relationship in project.dependencies:
             if check_failure(relationship.dependency):
                 # if there is a "last successful build", we'll use that
@@ -253,4 +287,6 @@
     
     def _finalize(self, workspace):
         DumbAlgorithm._finalize(self, workspace)
-        self.persistence_helper.stop_using_previous_build(workspace)
\ No newline at end of file
+        self.persistence_helper.stop_using_previous_build(workspace)
+        self.project_model_list = []
+        self.module_model_list = []

Copied: gump/branches/Gump3/pygump/python/gump/engine/at_parser.py (from r210019, gump/branches/Gump3/pygump/python/gump/engine/verifier.py)
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/engine/at_parser.py?p2=gump/branches/Gump3/pygump/python/gump/engine/at_parser.py&p1=gump/branches/Gump3/pygump/python/gump/engine/verifier.py&r1=210019&r2=210128&rev=210128&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/engine/verifier.py (original)
+++ gump/branches/Gump3/pygump/python/gump/engine/at_parser.py Mon Jul 11 06:41:39 2005
@@ -14,157 +14,56 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""This module verifies a gump object model."""
+"""This module replaces '@@VARIABLE@@' properties in an XML DOM."""
 
 __copyright__ = "Copyright (c) 2004-2005 The Apache Software Foundation"
 __license__   = "http://www.apache.org/licenses/LICENSE-2.0"
 
-import logging
-import os
-import sys
-
 from xml import dom
 from xml.dom import minidom
 
-from gump.model import *
-
-from gump.engine import EngineError
-from gump.util import ansicolor
-
-class VerificationError(EngineError):
-    """Error raised by the verifier if the model is not valid."""
-    pass
-
-class CyclicDependencyError(VerificationError):
-    """Error raised by the verifier if the model contains one or more cyclic
-    dependencies. The cycles property will contain an array of cycles, where
-    a cycle again is an array of projects that together make up a cycle."""
-    #TODO think about error hierarchies in gump and decide if this is the way
-    #     we want to implement them
-    pass
-
-def print_cyclic_trace(cycles, handler):
-    for cycle in cycles: # isn't there a level of nesting too much here???
-        for chain in cycle:
-            msg = ""
-            indent = "  "
-            for project in chain:
-                msg += "%s%s -->\n" % (indent, project.name)
-                indent += "  "
-            msg = ansicolor.Bright_Red + msg[:-5] + ansicolor.Black
-            handler(msg)
-    
-class AbstractErrorHandler:
-    """Base class for supporting configurable error recovery. Instead of
-    raising exceptions, supportive classes will pass the error to an instance
-    of this class. This allows clients to recover from errors more gracefully.
-    This default implementation tries to call a handleError() method on
-    itself, and raises the error if that is not possible.
-    
-    Subclasses should implement a handleError(error) method, where the
-    provided error argument is normally an instance of Exception.
-    
-    This setup is similar to that used by the SAX libraries."""
-    #TODO maybe move this elsewhere?
-    def _handleError(self):
-        if not hasattr(self, 'handleError'): raise
-        if not callable(self.handleError): raise
-        self.handleError()
-
-class LoggingErrorHandler(AbstractErrorHandler):
-    """Naive error handler which logs all errors and then swallows them."""
-    def __init__(self, log):
-        self.log = log
-
-    def handleError(self):
-        errorType = sys.exc_info()[0]
-        if errorType is CyclicDependencyError:
-            errorValue = sys.exc_info()[1]
-            self.log.error("The following cyclic dependencies were found:")
-            print_cyclic_trace(errorValue, self.log.error)
-            self.log.error("The projects involved will not be built!")
-        else:
-            raise
-
-class Verifier:
-    """Determines whether a finished gump model conforms to certain contracts.
-    
-    Those contracts are not currently completely specified, but it is somewhat
-    possible to digest them from the model documentation. However, the
-    verifier itself together with its unit tests is probably the only "hard"
-    specification of those contracts."""
-    def __init__(self, walker, errorHandler=AbstractErrorHandler()):
-        assert hasattr(walker, "walk")
-        assert callable(walker.walk)
-        
-        self.walker = walker
-        self.errorHandler = errorHandler
-        
-    def verify(self, workspace):
-        """Sends VerificationError objects to the errorHandler argument if the
-        provided model contains errors. If no errorHandler is provided, the
-        exceptions are 'raise'd."""
-        from gump.plugins import AbstractPlugin
-        visitor = AbstractPlugin(None)
-        (visited_repositories, visited_modules, visited_projects) = self.walker.walk(workspace,
visitor)
-        
-        if len(visited_projects) != len(workspace.projects):
-            # some projects weren't visited! Those indicate cycles...
-            unvisited = []
-            
-            for p in workspace.projects.values():
-                if not p in visited_projects:
-                    unvisited.append(p)
-            
-            cycles = self._find_cycles(unvisited[:])
-            workspace.cycles = cycles
-            workspace.unvisited = unvisited
+class AtParser:
+    def __init__(self, dictionary):
+        self.dictionary = dictionary
+        
+    def parse(self, document):
+        replace_at_properties(document.documentElement, self.dictionary)
+        return document
+
+
+def replace_at_properties(node, dictionary):
+    if node.hasAttributes():
+        attributes = node.attributes
+        i = 0
+        while i < attributes.length:
+            attribute = attributes.item(i)
+            i = i + 1
+            if not attribute: continue
+            attribute.nodeValue = _replace_at_properties_in_string(attribute.nodeValue, dictionary)
+    
+    if node.hasChildNodes():
+        children = node.childNodes
+        i = 0
+        while i < children.length:
+            child = children.item(i)
+            i = i + 1
+            if not child: continue
+            if child.nodeType == dom.Node.TEXT_NODE:
+                child.nodeValue = _replace_at_properties_in_string(child.nodeValue, dictionary)
+                continue
+
+            # recurse
+            if child.nodeType == dom.Node.ELEMENT_NODE:
+                replace_at_properties(child, dictionary)
+                continue
             
-            try:
-                raise CyclicDependencyError, cycles
-            except:
-                self.errorHandler._handleError()
-    
-    def _find_cycles(self,projects):
-        """Brute-force find all cycles.
-        
-        1) depth-first traverse all paths extending from each project
-           (the "needle")
-        2) use a stack for documenting the current path traversal
-        2) look for cycles in those paths involving the needle
-           2.a) avoid traversing cycles not involving the needle
-                by coloring nodes on visit, making sure to visit
-                them only once
-           2.b) store a cycle when its found
-        3) return an array containing an array of cycles"""
-        cycles = []
-        for project in projects:
-            needle = project
-            visited = []
-            stack = [project]
-            self._visit(project,visited,stack,needle,cycles)
-        
-        return cycles
-    
-    def _visit(self,project,visited,stack,needle,cycles):
-        # debuggging statements...
-        #msg = "Visiting: %s, stack=[" % project.name
-        #for p in stack:
-        #    msg += p.name + ","
-        #msg = msg[:-1] + "]"
-        #print msg
-        
-        visited.append(project)
-        for relationship in project.dependencies:
-            dependency = relationship.dependency
-            stack.append(dependency)
-            if dependency == needle: # cycle involving needle!
-                cycles.append(stack[:])
-                visited.append(dependency)
-            else:
-                if not dependency in visited:
-                    self._visit(dependency,visited,stack,needle,cycles)
-
-            stack.pop() # get rid of this dependency, we'll be looking
-                        # at the next dependency in the next iteration of
-                        # the for loop
+
+def _replace_at_properties_in_string(string, dictionary):
+    if not isinstance(string, basestring):
+        return string
+    
+    newstring = string
+    for k,v in dictionary.iteritems():
+        searchstring = "@@%s@@" % k
+        newstring = newstring.replace(searchstring,v)
+    return newstring
\ No newline at end of file

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=210128&r1=210127&r2=210128&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/model/__init__.py (original)
+++ gump/branches/Gump3/pygump/python/gump/model/__init__.py Mon Jul 11 06:41:39 2005
@@ -19,6 +19,21 @@
 __copyright__ = "Copyright (c) 2004-2005 The Apache Software Foundation"
 __license__   = "http://www.apache.org/licenses/LICENSE-2.0"
 
+# DEVELOPMENT NOTES:
+# The gump.model package is supposed to be completely "passive", eg
+# instantiating or modifying any of the classes in this package should be
+# completely free of "side effects" such as database calls or directory
+# creation.
+#
+# These side effects should be dealt with in other parts of the codebase, such
+# as the gump.engine or the gump.plugins.
+#
+# In addition, the gump.model package is supposed to be devoid of any "logic"
+# that goes above and beyond simple model integrity validation (eg basic
+# assert statements for validating arguments).
+#
+# Model-related logic should go into gump.model.util.
+
 import os
         
 class Error(Exception):

Modified: gump/branches/Gump3/pygump/python/gump/plugins/builder.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/plugins/builder.py?rev=210128&r1=210127&r2=210128&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/plugins/builder.py (original)
+++ gump/branches/Gump3/pygump/python/gump/plugins/builder.py Mon Jul 11 06:41:39 2005
@@ -64,7 +64,7 @@
             self.log.debug("Perform %s on %s" % (command, project))
             self.method(project, command)
     
-    def _do_run_command(self, command, args, workdir, shell=False):
+    def _do_run_command(self, command, args, workdir, shell=False, no_cleanup=False):
         """Utility method for actually executing commands and storing their
            results within the model.
         
@@ -74,6 +74,9 @@
           - args    -- the action to take (including, for example, a script
                        name)
         """
+        # see gump.plugins.java.builder.AntPlugin for information on the
+        # no_cleanup flag
+        
         # running subprocess.Popen with shell=True results in "sh -c", which is
         # not what we want, since our shell=True indicates we're actually running
         # a shell script, and potentially using a different shell!
@@ -94,13 +97,15 @@
         outputfile = None
         try:
             outputfile = open(outputfilename,'wb')
-            cmd = Popen(myargs,shell=False,cwd=workdir,stdout=outputfile,stderr=STDOUT,env=command.env)
+            cmd = Popen(myargs,shell=False,cwd=workdir,stdout=outputfile,stderr=STDOUT,env=command.env,
no_cleanup=no_cleanup)
             #command.build_log = cmd.communicate()[0]
             command.build_exit_status = cmd.wait()
 
             outputfile.close()
             outputfile = open(outputfilename,'rb')
-            command.build_log = outputfile.read()
+            # we need to avoid Unicode errors when people put in 'fancy characters'
+            # into build outputs
+            command.build_log = unicode(outputfile.read(), 'iso-8859-1')
         finally:
             if outputfile:
                 try: outputfile.close()

Modified: gump/branches/Gump3/pygump/python/gump/plugins/java/builder.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/plugins/java/builder.py?rev=210128&r1=210127&r2=210128&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/plugins/java/builder.py (original)
+++ gump/branches/Gump3/pygump/python/gump/plugins/java/builder.py Mon Jul 11 06:41:39 2005
@@ -69,6 +69,18 @@
         if ant.target: args += [ant.target]
         if self.debug: args += ["-debug"]
         
+        # TODO properties
+        # TODO parse @@DATE@@ from properties
+        
         # run it
-        self._do_run_command(ant, args, projectpath)
+        #
+        # Setting the process group id (os.setpgrp()) as we do in
+        # gump.util.executor sometimes causes a deadlock problem when ant
+        # is forking off new java processes. This is because of problems with
+        # Runtime.exec() (there are a few it seems, for example
+        #   http://bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=4052517)
+        # Our (rather insane!) workaround is to not set the process group id,
+        # which means our "get rid of all children" algorithm is disabled for
+        # all ant-based builds.
+        self._do_run_command(ant, args, projectpath, no_cleanup=True)
         

Modified: gump/branches/Gump3/pygump/python/gump/test/testConfig.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/test/testConfig.py?rev=210128&r1=210127&r2=210128&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/test/testConfig.py (original)
+++ gump/branches/Gump3/pygump/python/gump/test/testConfig.py Mon Jul 11 06:41:39 2005
@@ -100,6 +100,8 @@
         class MockConfig:
             debug = False
             quiet = False
+            local_repository_name = False
+            local_module_name = False
         
         mock = MockConfig()
         run_config_hooks(mock)
@@ -108,6 +110,12 @@
         run_config_hooks(mock)
         
         mock.debug = True
+        run_config_hooks(mock)
+        
+        mock.local_repository_name = "test"
+        run_config_hooks(mock)
+        
+        mock.local_module_name = "test"
         run_config_hooks(mock)
 
     def test_get_config(self):

Modified: gump/branches/Gump3/pygump/python/gump/util/executor.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/util/executor.py?rev=210128&r1=210127&r2=210128&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/util/executor.py (original)
+++ gump/branches/Gump3/pygump/python/gump/util/executor.py Mon Jul 11 06:41:39 2005
@@ -48,8 +48,25 @@
 if sys.platform == "win32":
     from subprocess import PIPE
     from subprocess import STDOUT
-    from subprocess import Popen
+    import subprocess
     
+    class Popen(subprocess.Popen):
+        """This is a thin wrapper around subprocess.Popen which does fancy logging."""
+        def __init__(self, args, bufsize=0, executable=None,
+                     stdin=None, stdout=None, stderr=None,
+                     preexec_fn=None, close_fds=False, shell=False,
+                     cwd=None, env=None, universal_newlines=False,
+                     startupinfo=None, creationflags=0, no_cleanup=False):
+            # a logger can be set for this module to make us log commands
+            if _log:
+                _log.info("        Executing command:\n      %s'%s'%s\n       in directory
'%s'" % (ansicolor.Blue, " ".join(args), ansicolor.Black, os.path.abspath(cwd or os.curdir)))
+
+            subprocess.Popen.__init__(self, args, bufsize=bufsize, executable=executable,
+                         stdin=stdin, stdout=stdout, stderr=stderr,
+                         preexec_fn=preexec_fn, close_fds=close_fds, shell=shell,
+                         cwd=cwd, env=env, universal_newlines=universal_newlines,
+                         startupinfo=startupinfo, creationflags=creationflags)
+
     def clean_up_processes(timeout):
         """This function can be called prior to program exit to attempt to
         kill all our running children that were created using this module.
@@ -62,41 +79,27 @@
     import subprocess
     import signal
     import errno
+    import tempfile
     from subprocess import PIPE
     from subprocess import STDOUT
 
-    def _get_new_process_group():
-        """Get us an unused (or so we hope) process group."""
-        pid = os.fork()
-        gid = pid # that *should* be correct. However, let's actually
-                  # create something in that group.
-        if pid == 0:
-            # Child
-            
-            # ensure a process group is created
-            os.setpgrp()
-            
-            # sleep for ten days to keep the process group around
-            # for "a while"
-            import time
-            time.sleep(10*24*60*60)
-            os._exit(0)
-        else:
-            # Parent
-    
-            # wait for child a little so it can set its group
-            import time
-            time.sleep(1)
-            
-            # get the gid for the child
-            gid = os.getpgid(pid)
-        
-        return gid
-
-    # This is the group we chuck our children in. We don't just want to
-    # use our own group since we don't want to kill ourselves prematurely!
-    _our_process_group = _get_new_process_group()
+    temp_dir = tempfile.mkdtemp("gump_util_executor")
+    process_list_filename = os.path.join(temp_dir, "processlist.pids")
 
+    def savepgid(filename):
+        """Function called from Popen child process to create new process groups."""
+        os.setpgrp()
+        f = None
+        try:
+            grp = os.getpgrp()
+            f = open(filename,'a+')
+            f.write("%d" % grp)
+            f.write('\n')
+        finally:
+            if f:
+                try: f.close()
+                except: pass
+            
     class Popen(subprocess.Popen):
         """This is a thin wrapper around subprocess.Popen which handles
         process group management. The gump.util.executor.clean_up_processes()
@@ -106,35 +109,67 @@
                      stdin=None, stdout=None, stderr=None,
                      preexec_fn=None, close_fds=False, shell=False,
                      cwd=None, env=None, universal_newlines=False,
-                     startupinfo=None, creationflags=0):
-            """Create a new Popen instance that delegates to the
-            subprocess Popen."""
-            if not preexec_fn:
-                # setpgid to the gump process group inside the child
-                pre_exec_function = lambda: os.setpgid(0, _our_process_group)
-            else:
-                # The below has a "stupid lambda trick" that makes the lambda
-                # evaluate a tuple of functions. This sticks our own function
-                # call in there while still supporting the originally provided
-                # function
-                pre_exec_function = lambda: (preexec_fn(),os.setpgid(0, _our_process_group))
-            
+                     startupinfo=None, creationflags=0, no_cleanup=False):
+            # see gump.plugins.java.builder.AntPlugin for information on the
+            # no_cleanup flag
+
             # a logger can be set for this module to make us log commands
             if _log:
                 _log.info("        Executing command:\n      %s'%s'%s\n       in directory
'%s'" % (ansicolor.Blue, " ".join(args), ansicolor.Black, os.path.abspath(cwd or os.curdir)))
-            
-            subprocess.Popen.__init__(self, args, bufsize=bufsize, executable=executable,
-                     stdin=stdin, stdout=stdout, stderr=stderr,
-                     # note our custom function in there...
-                     preexec_fn=pre_exec_function, close_fds=close_fds, shell=shell,
-                     cwd=cwd, env=env, universal_newlines=universal_newlines,
-                     startupinfo=startupinfo, creationflags=creationflags)
+
+            if not no_cleanup:
+                global process_list_filename
+                """Create a new Popen instance that delegates to the
+                subprocess Popen."""
+                if not preexec_fn:
+                    # setpgid to the gump process group inside the child
+                    pre_exec_function = lambda: savepgid(process_list_filename)
+                else:
+                    # The below has a "stupid lambda trick" that makes the lambda
+                    # evaluate a tuple of functions. This sticks our own function
+                    # call in there while still supporting the originally provided
+                    # function
+                    pre_exec_function = lambda: (preexec_fn(),savepgid(process_list_filename))
+                
+                
+                subprocess.Popen.__init__(self, args, bufsize=bufsize, executable=executable,
+                         stdin=stdin, stdout=stdout, stderr=stderr,
+                         # note our custom function in there...
+                         preexec_fn=pre_exec_function, close_fds=close_fds, shell=shell,
+                         cwd=cwd, env=env, universal_newlines=universal_newlines,
+                         startupinfo=startupinfo, creationflags=creationflags)
+            else:
+                subprocess.Popen.__init__(self, args, bufsize=bufsize, executable=executable,
+                         stdin=stdin, stdout=stdout, stderr=stderr,
+                         # note our custom function is *not* in there...
+                         preexec_fn=preexec_fn, close_fds=close_fds, shell=shell,
+                         cwd=cwd, env=env, universal_newlines=universal_newlines,
+                         startupinfo=startupinfo, creationflags=creationflags)
+                
 
     def clean_up_processes(timeout=300):
         """This function can be called prior to program exit to attempt to
         kill all our running children that were created using this module."""
     
-        pgrp_list = [_our_process_group]
+        global process_list_filename
+        global temp_dir
+
+        pgrp_list = []
+
+        f = None
+        try:
+            f = open(process_list_filename, 'r')
+            pgrp_list = [int(line) for line in f.read().splitlines()]
+        except:
+            if f: 
+                try: f.close()
+                except: pass
+        try:
+            import shutil
+            shutil.rmtree(temp_dir)
+        except:
+            pass
+        
         # send SIGTERM to everything, and update pgrp_list to just those
         # process groups which have processes in them.
         _kill_groups(pgrp_list, signal.SIGTERM)

Modified: gump/branches/Gump3/pygump/python/main.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/main.py?rev=210128&r1=210127&r2=210128&view=diff
==============================================================================
--- gump/branches/Gump3/pygump/python/main.py (original)
+++ gump/branches/Gump3/pygump/python/main.py Mon Jul 11 06:41:39 2005
@@ -176,6 +176,22 @@
                       dest="attach_wing",
                       default=False,
                       help="Run within the Wing IDE Debugger")
+    parser.add_option("--local-repository-name",
+                      action="store",
+                      dest="local_repository_name",
+                      default=None,
+                      help="Repository name for 'installed packages'")
+    parser.add_option("--local-module-name",
+                      action="store",
+                      dest="local_module_name",
+                      default=None,
+                      help="Module name for 'installed packages'")
+                      
+    parser.add_option("-p",
+                      "--project",
+                      action="append",
+                      dest="project_name",
+                      help="Specify a regular expression specifying project(s) to be updated&built\n
          Can be provided multiple times.")
                       
     return parser
 
@@ -461,6 +477,7 @@
             sys.exit(2)
         
         # Copy over the dbstub if it isn't there already
+        wingdbstubpath = None
         try:
             wingdbstubpath = os.path.join(options.homedir,"pygump","python","wingdbstub.py")
             if not os.path.isfile(wingdbstubpath):
@@ -500,9 +517,6 @@
         log.debug('      %s' % (sys.argv))
     
         # validate options and arguments
-        if not hasattr(options, "projects"):
-            log.debug("No projects to build set, defaulting to 'all'")
-            options.projects = ["all"]
         if not os.path.exists(options.paths_workspace):
             abspath = os.path.join(options.paths_home, options.paths_workspace)
             if os.path.exists(abspath):



Mime
View raw message