Return-Path: Delivered-To: apmail-gump-commits-archive@www.apache.org Received: (qmail 83893 invoked from network); 28 Apr 2005 13:00:23 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 28 Apr 2005 13:00:23 -0000 Received: (qmail 77115 invoked by uid 500); 28 Apr 2005 13:01:28 -0000 Mailing-List: contact commits-help@gump.apache.org; run by ezmlm Precedence: bulk Reply-To: commits@gump.apache.org List-Help: List-Unsubscribe: List-Post: List-Id: Delivered-To: mailing list commits@gump.apache.org Received: (qmail 77096 invoked by uid 99); 28 Apr 2005 13:01:28 -0000 X-ASF-Spam-Status: No, hits=0.2 required=10.0 tests=NO_REAL_NAME X-Spam-Check-By: apache.org Received: from minotaur.apache.org (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.28) with SMTP; Thu, 28 Apr 2005 06:01:27 -0700 Received: (qmail 83852 invoked by uid 65534); 28 Apr 2005 13:00:20 -0000 Message-ID: <20050428130020.83848.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Subject: svn commit: r165133 - in /gump/branches/Gump3/pygump: gump.log.config python/gump/config.py python/gump/engine/__init__.py python/gump/engine/walker.py python/gump/plugins/java/ python/gump/plugins/java/__init__.py python/gump/plugins/java/builder.py python/gump/plugins/logreporter.py Date: Thu, 28 Apr 2005 13:00:18 -0000 To: commits@gump.apache.org From: ajack@apache.org X-Mailer: svnmailer-1.0.0-dev X-Virus-Checked: Checked X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: ajack Date: Thu Apr 28 06:00:16 2005 New Revision: 165133 URL: http://svn.apache.org/viewcvs?rev=3D165133&view=3Drev Log: Start work on ClasspathPlugin and AntPlugin. Added: gump/branches/Gump3/pygump/python/gump/plugins/java/ gump/branches/Gump3/pygump/python/gump/plugins/java/__init__.py gump/branches/Gump3/pygump/python/gump/plugins/java/builder.py Modified: gump/branches/Gump3/pygump/gump.log.config gump/branches/Gump3/pygump/python/gump/config.py gump/branches/Gump3/pygump/python/gump/engine/__init__.py gump/branches/Gump3/pygump/python/gump/engine/walker.py gump/branches/Gump3/pygump/python/gump/plugins/logreporter.py Modified: gump/branches/Gump3/pygump/gump.log.config URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/gump.log.conf= ig?rev=3D165133&r1=3D165132&r2=3D165133&view=3Ddiff =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- gump/branches/Gump3/pygump/gump.log.config (original) +++ gump/branches/Gump3/pygump/gump.log.config Thu Apr 28 06:00:16 2005 @@ -26,7 +26,7 @@ qualname=3Dmodeller =20 [logger_walker] -level=3DDEBUG +level=3DINFO handlers=3Dstdout,filehandler propagate=3D0 qualname=3Dwalker @@ -42,6 +42,12 @@ handlers=3Dstdout,filehandler propagate=3D0 qualname=3Dutil.db + +[logger_plugin_error-handler] +level=3DDEBUG +handlers=3Dstdout,filehandler +propagate=3D0 +qualname=3Dplugin.error-handler =20 [logger_plugin_dynagumper] level=3DDEBUG Modified: gump/branches/Gump3/pygump/python/gump/config.py URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/c= onfig.py?rev=3D165133&r1=3D165132&r2=3D165133&view=3Ddiff =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- gump/branches/Gump3/pygump/python/gump/config.py (original) +++ gump/branches/Gump3/pygump/python/gump/config.py Thu Apr 28 06:00:16 20= 05 @@ -103,14 +103,18 @@ from gump.plugins.instrumentation import TimerPlugin pre_process_plugins.append(TimerPlugin("run_start")) =20 - if config.do_update: + if config.do_update: =20 + pre_process_plugins.append(TimerPlugin("update_start")) from gump.plugins.updater import CvsUpdater, SvnUpdater - #pre_process_plugins.append(CvsUpdater(config.paths_work)) - #pre_process_plugins.append(SvnUpdater(config.paths_work)) - =20 + pre_process_plugins.append(CvsUpdater(config.paths_work)) + pre_process_plugins.append(SvnUpdater(config.paths_work)) + pre_process_plugins.append(TimerPlugin("update_end")) + =20 plugins =3D [] # TODO: append more plugins here... =20 + plugins.append(TimerPlugin("build_start")) + =20 from gump.plugins import LoggingPlugin =20 =20 @@ -124,10 +128,10 @@ =20 from gump.plugins.builder import ScriptBuilderPlugin plugins.append(ScriptBuilderPlugin(config.paths_work,buildlog)) - #from gump.plugins.java.builder import ClasspathPlugin - #plugins.append(ClasspathPlugin(config.paths_work,buildlog)) - #from gump.plugins.java.builder import AntPlugin - #plugins.append(AntPlugin(config.paths_work,buildlog)) + from gump.plugins.java.builder import ClasspathPlugin + plugins.append(ClasspathPlugin(config.paths_work,buildlog)) + from gump.plugins.java.builder import AntPlugin + plugins.append(AntPlugin(config.paths_work,buildlog)) =20 post_process_plugins =3D [] # TODO: append more plugins here... @@ -139,11 +143,14 @@ dynagumplog =3D get_logger(config, "plugin.dynagumper") post_process_plugins.append(Dynagumper(db, dynagumplog)) =20 + plugins.append(TimerPlugin("build_end")) + if config.debug: reportlog =3D get_logger(config, "plugin.logger") from gump.plugins.logreporter import LogReporterPlugin post_process_plugins.append(LogReporterPlugin(reportlog)) - + =20 + # Give us an insight to what we have cooking... for plugin in pre_process_plugins: log.debug("Preprocessor : %s " % `p= lugin`) for plugin in plugins: log.debug("Processor : %s " % `plugin`) for plugin in post_process_plugins: log.debug("Postprocessor: %s " % `= plugin`) @@ -206,9 +213,14 @@ """Provide a logging implementation for the given level and name.""" logging.basicConfig() log =3D logging.getLogger(name) - log.setLevel(config.log_level) + print 'Got Logger %s for %s' % (log,name) + # Let the file decide ... log.setLevel(config.log_level) return log =20 +def shutdown_logging(): + """Perform orderly logging shutdown""" + logging.shutdown() + =20 =20 def get_db(log,config): """Provide a database implementation.""" Modified: gump/branches/Gump3/pygump/python/gump/engine/__init__.py URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/e= ngine/__init__.py?rev=3D165133&r1=3D165132&r2=3D165133&view=3Ddiff =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- gump/branches/Gump3/pygump/python/gump/engine/__init__.py (original) +++ gump/branches/Gump3/pygump/python/gump/engine/__init__.py Thu Apr 28 06= :00:16 2005 @@ -109,6 +109,8 @@ =20 # run it engine.run() + =20 + shutdown_logging() =20 =20 def _banner(version): @@ -221,10 +223,10 @@ self.workspace_verifier.verify(workspace) =20 # * Pfew! All done. Now actually start *doing* stuff. - self.walker.walk(workspace, self.pre_process_visitor) + self.walker.walk(workspace, self.pre_process_visitor, 'pre_pro= cess') # (visited_repositories, visited_modules, visited_projects) = =3D \ - self.walker.walk(workspace, self.visitor) - self.walker.walk(workspace, self.post_process_visitor) + self.walker.walk(workspace, self.visitor, 'process') + self.walker.walk(workspace, self.post_process_visitor, 'post_p= rocess') =20 # That's it? Yeah! All other functionality is in the visitors = :-D except: Modified: gump/branches/Gump3/pygump/python/gump/engine/walker.py URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/e= ngine/walker.py?rev=3D165133&r1=3D165132&r2=3D165133&view=3Ddiff =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- gump/branches/Gump3/pygump/python/gump/engine/walker.py (original) +++ gump/branches/Gump3/pygump/python/gump/engine/walker.py Thu Apr 28 06:0= 0:16 2005 @@ -37,7 +37,7 @@ =20 self.log =3D log =20 - def walk(self, workspace, visitor): + def walk(self, workspace, visitor, description=3D'unspecified'): """Walks a gump tree using inverted topsort. =20 Arguments: @@ -51,27 +51,30 @@ visited_modules =3D [] visited_projects =3D [] =20 + self.log.debug('Visitor %s initialize, on %s walk.' % (`visitor`, = description)) visitor._initialize() =20 - self.log.debug('Visit W/S : ' + `workspace`) + self.log.debug('Visit W/S %s for %s walk.' % (`workspace`, descrip= tion)) visitor._visit_workspace(workspace) list =3D self._topsort_projects(workspace) =20 for project in list: if not project.module in visited_modules: if not project.module.repository in visited_repositories: - self.log.debug('Visit Repo : ' + `project.module.repos= itory`) + self.log.debug('Visit Repo %s for %s walk.' % \ + (`project.module.repository`, descripti= on)) visitor._visit_repository(project.module.repository) visited_repositories.append(project.module.repository) =20 - self.log.debug('Visit Module : ' + `project.module`) + self.log.debug('Visit Module %s for %s walk.' % (`project.= module`,description)) visitor._visit_module(project.module) visited_modules.append(project.module) =20 - self.log.debug('Visit Project : ' + `project`) + self.log.debug('Visit Project %s for %s walk.' % (`project`, d= escription)) visitor._visit_project(project) visited_projects.append(project) =20 + self.log.debug('Visitor %s finalize, on %s walk.' % (`visitor`, de= scription)) visitor._finalize() return (visited_repositories, visited_modules, visited_projects) =20 Added: gump/branches/Gump3/pygump/python/gump/plugins/java/__init__.py URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/p= lugins/java/__init__.py?rev=3D165133&view=3Dauto =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- gump/branches/Gump3/pygump/python/gump/plugins/java/__init__.py (added) +++ gump/branches/Gump3/pygump/python/gump/plugins/java/__init__.py Thu Apr= 28 06:00:16 2005 @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +# Copyright 2004-2005 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +#=20 +# http://www.apache.org/licenses/LICENSE-2.0 +#=20 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Contains Java specific Classes/Plugins """ \ No newline at end of file Added: gump/branches/Gump3/pygump/python/gump/plugins/java/builder.py URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/p= lugins/java/builder.py?rev=3D165133&view=3Dauto =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- gump/branches/Gump3/pygump/python/gump/plugins/java/builder.py (added) +++ gump/branches/Gump3/pygump/python/gump/plugins/java/builder.py Thu Apr = 28 06:00:16 2005 @@ -0,0 +1,235 @@ +#!/usr/bin/env python + +# Copyright 2004-2005 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +#=20 +# http://www.apache.org/licenses/LICENSE-2.0 +#=20 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +__copyright__ =3D "Copyright (c) 2004-2005 The Apache Software Foundation" +__license__ =3D "http://www.apache.org/licenses/LICENSE-2.0" + +import os +import sys +from os.path import abspath, join, isfile + +from gump.model import Script, Error, Project, Ant, Dependency, Homedir, J= ar +from gump.model.util import get_project_directory +from gump.plugins import AbstractPlugin +from gump.util.executor import Popen, PIPE, STDOUT + +class BuilderPlugin(AbstractPlugin): + """Execute all commands for all projects.""" + def __init__(self, workdir, log, cmd_clazz, method): + self.workdir =3D workdir + self.log =3D log + self.cmd_clazz =3D cmd_clazz + self.method =3D method =20 + + def visit_project(self, project): + """ Dispatch for each matching command (matching by class type) ""= " =20 + assert isinstance(project, Project) + self.log.debug("Visit %s looking for %s" % (project,self.cmd_clazz= )) + for command in [command for command in project.commands if isinsta= nce(command,self.cmd_clazz)]: + try: =20 + self.log.debug("Perform %s on %s" % (command, project)) + self.method(project, command) + except Exception: + self.log.exception("Failed...") + + +class ArtifactPath(object): + """Represents an artifact within a path""" + def __init__(self,id,path,description=3DNone): + self.id=3Did + self.path =3D path + self.description=3Ddescription + =20 + def __eq__(self,other): + return (self.path =3D=3D other.path) + =20 + def __str__(self): + return self.path + =20 +class Classpath(object): + """Represents a list of artifacts + + Has the following properties: + =20 + - id -- identifier + - parts -- an array of ArtifactPath objects + - state -- state of Artifacts: + unknown + complete + stale (some from repository) + incomplete (some missing)""" + def __init__(self, id): + self.id =3D id + self.parts =3D [] + self.state=3D'unknown' + =20 + def __add__(self,other): + if not isinstance(other,ArtifactPath): + other=3DArtifactPath("Unknown",other,"Unspecified") + if not other in self.parts: + self.parts.append(other) + return self + =20 + def __str__(self): + import string + return string.join([ part.path for part in self.parts ], os.pathse= p) + =20 +class ClasspathPlugin(BuilderPlugin): + """Generate build attributes (e.g. CLASSAPATH) for a builder.""" + def __init__(self, workdir, log): + BuilderPlugin.__init__(self, workdir, log, Ant, self._forge_classp= aths) + =20 + def _forge_classpaths(self, project, ant): =20 + + # Stub them out... + ant.classpath=3DClasspath("Standard") + ant.boot_classpath=3DClasspath("Boot") + =20 + # Flesh them out... + self._calculateClasspaths(project,ant) + + def _calculateClasspaths(self, project, ant): + """Generate the classpath lists""" + #TODO This ought be under "java" not under "Ant". =20 + =20 + #TODO Need " elements + =20 + # Recurse into dependencies + visited=3D[] + for dependency in project.dependencies: + self._calculateDependencyContributions(ant,dependency,1,visite= d) + =20 + def _calculateDependencyContributions(self,ant,dependency,depth,visite= d): =20 + assert isinstance(dependency, Dependency) + =20 + #TODO Check NO_CLASSPATH if dependency.dependencyInfo + if dependency in visited: return + + # Access the players + project=3Ddependency.dependency + projectpath =3D get_project_directory(self.workdir,project) + =20 + #TODO Do we need a filter here? Are all dependency infos + # appropriate, or not? + for info in [info for info in dependency.dependencyInfo]: = =20 + =20 + # The dependency drivers... + # + # runtime (i.e. this is a runtime dependency) + # inherit (i.e. inherit stuff from a dependency) + # ids (i.e. what output ids to select) + # + runtime=3Dinfo.runtime + inherit=3Dinfo.inherit + ids=3Dinfo.specific_output_ids + =20 + # Explain.. + depend_str=3D'' + if inherit:=20 + if depend_str: depend_str +=3D ', ' + depend_str +=3D 'Inherit:'+dependency.inherit + if runtime:=20 + if depend_str: depend_str +=3D ', ' + depend_str +=3D 'Runtime' + =20 + # Append Outputs for this project + # (respect ids --- none means 'all) + project_ids=3D[] + for output in project.outputs: + # Store for double checking + if output.id: project_ids.append(output.id) + =20 + # If 'all' or in ids list: + if (not ids) or (output.id in ids): =20 + if ids: depend_str +=3D ' ID =3D ' + output.id + =20 + if isinstance(output,Homedir): + path =3D os.path.join(projectpath,output.directory= ) + elif isinstance(output,Jar): + path =3D os.path.join(projectpath,output.name) + else: + raise Error, "Unknown Output Type for %s: %s" % (s= elf.__class__.__name__, output.__class__.__name__) + =20 + artifact_path=3DArtifactPath(output.id,path,depend_str= )=20 + =20 + # Add to CLASSPATH (or BOOTCLASSPATH) + if not isinstance(output,Jar) or not output.add_to_boo= tclass_path: + ant.classpath +=3D artifact_path + else: + ant.boot_classpath +=3D artifact_path + + # Double check IDs (to reduce stale IDs in metadata) + if ids: + for id in ids: + if not id in project_ids: + self.log.warn("Invalid ID [" + id + "] for dependency = on [" + project.name + "]") + + visited.append(dependency) =20 + =20 + # Append sub-projects outputs, if inherited + for subdependency in project.dependencies: =20 + # + # For the main project we working on, we care about it's requ= est for inheritence + # but we don't recursively inherit. (i.e. we only do this at r= ecursion depth 1). + # + # If the dependency is set to 'all' (or 'hard') we inherit a= ll dependencies. + # If the dependency is set to 'runtime' we inherit all runtim= e dependencies. + # + # INHERIT_OUTPUTS (aka INHERIT_JARS) is more sticky, and we tr= ack that down (and down, ...). + # + for subinfo in subdependency.dependencyInfo: + if ( ( ( 1 =3D=3D depth ) and \ + (inherit in [ 'all', 'hard' ]) \ + or \ + (inherit =3D=3D 'runtime' and subdependency.isRu= ntime()) ) \ + or \ + ( inherit in [ 'outputs' ] ) ) : =20 + self._calculateDependencyContributions(ant,subdependen= cy,depth+1,visited) + =20 + =20 +class ArtifactPlugin(BuilderPlugin): + """Resolve all entries in the CLASSPATH|BOOT_CLASSPATH checking for ex= istence.=20 + When absent see if recent copies can be acquired from a repository.""" + def __init__(self,workdir, log): + BuilderPlugin.__init__(self, workdir, log, Ant, self._resolve_clas= spaths) + =20 + def _resolve_classpaths(self, project, ant): =20 + =20 + projectpath =3D get_project_directory(self.workdir,project) + =20 + self._resolve_classpath(ant.classpath) + self._resolve_classpath(ant.boot_classpath) + =20 + def _resolve_classpath(classpath): =20 + for artifact_path in ant.classpath: + if not os.path.exists(artifact_path.path): + #TODO Go find from Repository... + classpath.state=3D'incomplete' + =20 +class AntPlugin(BuilderPlugin): + """Execute all "ant" commands for all projects.""" + def __init__(self, workdir, log): + BuilderPlugin.__init__(self, workdir, log, Ant, self._do_ant) + =20 + def _do_ant(self, project, ant): =20 + projectpath =3D get_project_directory(self.workdir,project) + =20 + buildfile =3D abspath(join(projectpath, ant.name)) =20 + =20 + #TODO + import pprint + self.log.debug('CLASSPATH %s' % ant.classpath) + self.log.debug('BOOTCLASSPATH %s' % ant.boot_classpath) Modified: gump/branches/Gump3/pygump/python/gump/plugins/logreporter.py URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/p= lugins/logreporter.py?rev=3D165133&r1=3D165132&r2=3D165133&view=3Ddiff =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- gump/branches/Gump3/pygump/python/gump/plugins/logreporter.py (original) +++ gump/branches/Gump3/pygump/python/gump/plugins/logreporter.py Thu Apr 2= 8 06:00:16 2005 @@ -36,12 +36,15 @@ if container: if hasattr(container, "name"): name =3D "%s:%s" % (container.name, name) - + =20 + #self.log.debug(name) for attribute in dir(object): if attribute.endswith("_log"): logmsg =3D getattr(object,attribute) self.log.debug("---%s.%s----------------------------------= :\n%s" % (name, attribute, logmsg)) self.log.debug(hr) + #else: + # self.log.debug(' %s -> %s' % (attribute,getattr(object,at= tribute))) =20 if hasattr(object, 'exceptions'): import StringIO @@ -63,3 +66,7 @@ self._do_visit(project) for command in project.commands: self._do_visit(command,project) + =20 + def finalize(self): + self.log.debug(' Finished Outputting all log data (a lot)...') + self.log.debug(hr)