You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@gump.apache.org by bo...@apache.org on 2010/07/05 06:04:29 UTC
svn commit: r960435 - in /gump/live: ./ python/gump/core/model/project.py
python/gump/core/model/property.py python/gump/core/update/bzr.py
python/gump/core/update/darcs.py python/gump/core/update/hg.py
Author: bodewig
Date: Mon Jul 5 04:04:28 2010
New Revision: 960435
URL: http://svn.apache.org/viewvc?rev=960435&view=rev
Log:
separate id namespaces per output type
Modified:
gump/live/ (props changed)
gump/live/python/gump/core/model/project.py
gump/live/python/gump/core/model/property.py
gump/live/python/gump/core/update/bzr.py (props changed)
gump/live/python/gump/core/update/darcs.py (props changed)
gump/live/python/gump/core/update/hg.py (props changed)
Propchange: gump/live/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Jul 5 04:04:28 2010
@@ -1 +1 @@
-/gump/trunk:746160,746727,746892,747270,747272-747273,747656,748010,748018,748028,748661,748967,760784-761159,815848,953630-954169,955387,955837,956771,957107,957408,958453,958915,959344,959847
+/gump/trunk:746160,746727,746892,747270,747272-747273,747656,748010,748018,748028,748661,748967,760784-761159,815848,953630-954169,955387,955837,956771,957107,957408,958453,958915,959344,959847,960295,960297,960300,960303
Modified: gump/live/python/gump/core/model/project.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/model/project.py?rev=960435&r1=960434&r2=960435&view=diff
==============================================================================
--- gump/live/python/gump/core/model/project.py (original)
+++ gump/live/python/gump/core/model/project.py Mon Jul 5 04:04:28 2010
@@ -107,6 +107,7 @@ class Project(NamedModelObject, Statable
#############################################################
# Outputs (like jars, assemblies, poms ...)
#
+ # kept as {type => [outputs of that type]}
self.outputs = {}
self.outputs_expanded = False
@@ -253,13 +254,9 @@ class Project(NamedModelObject, Statable
return self.getModule().getViewUrl()
def addOutput(self, output):
- self.outputs[output.getName()] = output
-
- def getOutputCount(self):
- return len(self.outputs)
-
- def hasOutputWithId(self, id):
- return self.outputs.has_key(id)
+ if output.getType() not in self.outputs:
+ self.outputs[output.getType()] = []
+ self.outputs[output.getType()].append(output)
def hasLicense(self):
if self.license:
@@ -283,25 +280,27 @@ class Project(NamedModelObject, Statable
def getOutputs(self):
self.expand_outputs()
- return self.outputs.values()
+ return reduce(lambda l1, l2: l1 + l2, self.outputs.itervalues(), [])
def expand_outputs(self):
""" expands glob patterns in output names """
if (self.built or not self.hasBuilder()) and not self.outputs_expanded:
- for output in self.outputs.values():
- path = output.getPath()
- log.debug("glob expanding " + path)
- expansions = glob.glob(path)
- count = len(expansions)
- if count > 1:
- self.changeState(STATE_FAILED, REASON_MISSING_OUTPUTS)
- self.addError("%s matched %d files." % (path, count))
- elif count == 1:
- log.debug("replacing " + path + " with " + expansions[0])
- output.setPath(expansions[0])
- else:
- log.debug("didn't find any match for " + path)
- self.outputs_expanded = True
+ for l in self.outputs.itervalues():
+ for output in l:
+ path = output.getPath()
+ log.debug("glob expanding " + path)
+ expansions = glob.glob(path)
+ count = len(expansions)
+ if count > 1:
+ self.changeState(STATE_FAILED, REASON_MISSING_OUTPUTS)
+ self.addError("%s matched %d files." % (path, count))
+ elif count == 1:
+ log.debug("replacing " + path + " with " \
+ + expansions[0])
+ output.setPath(expansions[0])
+ else:
+ log.debug("didn't find any match for " + path)
+ self.outputs_expanded = True
def hasAnyOutputs(self):
"""
@@ -317,9 +316,6 @@ class Project(NamedModelObject, Statable
def getPackageNames(self):
return self.packageNames
- def getOutputAt(self, index):
- return self.getOutputs()[index]
-
def isRedistributable(self):
return self.redistributable or \
(self.module and self.module.isRedistributable())
@@ -558,56 +554,7 @@ class Project(NamedModelObject, Statable
#
# Resolve outputs
#
- outputTypes = ['jar',
- 'assembly',
- 'output',
- 'pom']
-
- for tag in outputTypes:
- for tdom in self.getDomChildIterator(tag):
- name = self.expandVariables(getDomAttributeValue(tdom, 'name'))
-
- if self.home and name:
- output = Output(name, tdom, self)
- output.complete()
- output.setPath(os.path.abspath(os.path.join(self.home,
- name)))
- if not output.getType() and tag != 'output':
- output.setType(tag)
- self.addOutput(output)
- else:
- self.addError('Missing \'name\' on <' + tag)
-
-
- # Fix 'ids' on all outputs which don't have them
- if self.hasOutputs():
- if 1 == self.getOutputCount():
- output = self.getOutputAt(0)
- if not output.hasId():
- self.addDebug('Sole output [' + \
- os.path.basename(output.getPath()) + \
- '] identifier set to project name')
- output.setId(self.getName())
- else:
- # :TODO: A work in progress, not sure how
- # we ought 'construct' ids.
- for output in self.getOutputs():
- if not output.hasId():
- basename = os.path.basename(output.getPath())
- newId = basename
- # Strip off .jar or .lib (note: both same length)
- if newId.endswith('.jar') or newId.endswith('.lib'):
- newId = newId[:-4]
- # Strip off -@@DATE@@
- datePostfix = '-' + str(default.date_s)
- if newId.endswith(datePostfix):
- reduction = -1 * len(datePostfix)
- newId = newId[:reduction]
- # Assign...
- self.addDebug('Output [' + basename + \
- '] identifier set to output ' + \
- 'basename: [' + newId + ']')
- output.setId(newId)
+ self.handle_outputs()
# Grab all the work
for w in self.getDomChildIterator('work'):
@@ -887,6 +834,81 @@ class Project(NamedModelObject, Statable
b.complete(self, workspace)
transferAnnotations(b, self)
+ def handle_outputs(self):
+ """
+ Parse all child elements that define outputs and resolve their ids
+ """
+ output_tags = ['jar',
+ 'assembly',
+ 'output',
+ 'pom']
+ rawOutputs = []
+ outputCountByType = {}
+
+ for tag in output_tags:
+ for tdom in self.getDomChildIterator(tag):
+ name = self.expandVariables(getDomAttributeValue(tdom, 'name'))
+
+ if self.home and name:
+ output = Output(name, tdom, self)
+ output.complete()
+ output.setPath(os.path.abspath(os.path.join(self.home,
+ name)))
+ if not output.getType() and tag != 'output':
+ output.setType(tag)
+ rawOutputs.append(output)
+ if output.getType() not in outputCountByType:
+ outputCountByType[output.getType()] = 1
+ else:
+ outputCountByType[output.getType()] = \
+ outputCountByType[output.getType()] + 1
+ else:
+ self.addError('Missing \'name\' on <' + tag)
+
+
+ # Fix 'ids' on all outputs which don't have them
+ for output in rawOutputs:
+ if not output.hasId():
+ if 1 == outputCountByType[output.getType()]:
+ self.addDebug('Sole ' + output.getType() + ' output [' + \
+ os.path.basename(output.getPath()) + \
+ '] identifier set to project name')
+ output.setId(self.getName())
+ else:
+ # :TODO: A work in progress, not sure how
+ # we ought 'construct' ids.
+ basename = os.path.basename(output.getPath())
+ newId = basename
+ # Strip off .jar or .lib (note: both same length)
+ if newId.endswith('.jar') or newId.endswith('.lib'):
+ newId = newId[:-4]
+ # Strip off -@@DATE@@
+ datePostfix = '-' + str(default.date_s)
+ if newId.endswith(datePostfix):
+ reduction = -1 * len(datePostfix)
+ newId = newId[:reduction]
+ # Assign...
+ self.addDebug('Output [' + basename + \
+ '] identifier set to output ' + \
+ 'basename: [' + newId + ']')
+ output.setId(newId)
+ self.addOutput(output)
+
+ # ensure id is unique per output type
+ for output_type in self.outputs.keys():
+ d = {}
+ remove = []
+ for o in self.outputs[output_type]:
+ if o.getId() in d:
+ self.addWarning("Multiple " + output_type + " outputs " \
+ + " use id " + o.getId() \
+ + " dropping " + o.getPath())
+ remove.append(o)
+ else:
+ d[o.getId()] = True
+ for o in remove:
+ self.outputs[output_type].remove(o)
+
class ProjectStatistics(Statistics):
"""Statistics Holder"""
def __init__(self, projectName):
Modified: gump/live/python/gump/core/model/property.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/model/property.py?rev=960435&r1=960434&r2=960435&view=diff
==============================================================================
--- gump/live/python/gump/core/model/property.py (original)
+++ gump/live/python/gump/core/model/property.py Mon Jul 5 04:04:28 2010
@@ -10,7 +10,7 @@
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
@@ -19,263 +19,307 @@
This module contains information on
"""
-from gump.core.model.object import *
-from gump.util.domutils import *
+import os
+import sys
+
+from gump.core.model.object import NamedModelObject
+from gump.util import getIndent
+from gump.util.domutils import getDomChildIterator, getDomAttributeValue, \
+ hasDomAttribute
+from gump.util.owner import Ownable
from types import NoneType
# represents a <property/> element
class Property(NamedModelObject):
-
- def __init__(self,name,dom,parent):
- NamedModelObject.__init__(self,name,dom,parent)
-
- self.value=None
-
-
- def setValue(self,value):
+
+ def __init__(self, name, dom, parent):
+ NamedModelObject.__init__(self, name, dom, parent)
+
+ self.value = None
+
+
+ def setValue(self, value):
"""
Set a value for this property
"""
self.value = value
-
+
def getValue(self):
"""
Get a value
"""
return self.value
-
+
# provide default elements when not defined in xml
- def complete(self,parent,workspace):
- if self.isComplete(): return
-
+ def complete(self, parent, workspace):
+ if self.isComplete():
+ return
+
# Don't normally allow blank properties
- blankOk=False
-
+ blankOk = False
+
if self.hasDomAttribute('value'):
- self.value=self.getDomAttributeValue('value','')
+ self.value = self.getDomAttributeValue('value', '')
if not self.value:
- self.value=''
+ self.value = ''
else:
- self.value=None
-
+ self.value = None
+
# Properties are either on the workspace, or on
# an ant entry within a project. Pick workspace or project.
- responsibleParty=workspace
- if not parent==workspace: responsibleParty=parent.getOwner()
-
+ responsibleParty = workspace
+ if not parent == workspace:
+ responsibleParty = parent.getOwner()
+
# Get what this might refer to.
- project=self.getDomAttributeValue('project')
- reference=self.getDomAttributeValue('reference')
-
+ project = self.getDomAttributeValue('project')
+ reference = self.getDomAttributeValue('reference')
+
#
# Do we have a reference to process?
#
- if reference=='home':
+ if reference == 'home':
if not workspace.hasProject(project):
- responsibleParty.addError('Cannot resolve homedir of *unknown* [' + project + ']')
+ responsibleParty.addError('Cannot resolve homedir of ' \
+ + '*unknown* [' + project + ']')
else:
self.setValue(workspace.getProject(project).getHomeDirectory())
-
- elif reference=='srcdir':
+
+ elif reference == 'srcdir':
if not workspace.hasProject(project):
- responsibleParty.addError('Cannot resolve srcdir of *unknown* [' + project + ']')
+ responsibleParty.addError('Cannot resolve srcdir of *unknown*' \
+ + ' [' + project + ']')
else:
- self.setValue(workspace.getProject(project).getModule().getWorkingDirectory())
-
- elif reference=='jarpath' or reference=='jar' \
- or reference=='outputpath' or reference=='output':
+ self.setValue(workspace.getProject(project).getModule() \
+ .getWorkingDirectory())
+
+ elif reference == 'jarpath' or reference == 'jar' \
+ or reference == 'outputpath' or reference == 'output':
if self.hasDomAttribute('project'):
if not workspace.hasProject(project):
responsibleParty.addError( \
- 'Cannot resolve output/outputpath of *unknown* [' + project + ']')
+ 'Cannot resolve output/outputpath of *unknown* [' \
+ + project + ']')
else:
- targetProject=workspace.getProject(project)
-
+ targetProject = workspace.getProject(project)
+ candidates = [o for o in targetProject.getOutputs()
+ if self.type_matches(o)]
+
if self.hasDomAttribute('id'):
- id=self.getDomAttributeValue('id')
+ idattr = self.getDomAttributeValue('id')
# Find the referenced id
- for output in targetProject.getOutputs():
- if output.getId()==id:
- if reference=='jarpath' or reference=='outputpath':
- self.setValue(output.getPath())
- else:
- self.setValue(output.getName())
+ for output in candidates:
+ if output.getId() == idattr:
+ self.setValueFromOutput(output, reference)
break
else:
- responsibleParty.addError( \
- ("Output with id %s was not found in project %s ") % \
- (id, targetProject.getName()))
-
- elif targetProject.getOutputCount()==1:
+ responsibleParty.addError( \
+ ("Output with id %s was not found in " + \
+ "project %s ") % \
+ (idattr, targetProject.getName()))
+
+ elif len(candidates) == 1:
# There is only one, so pick it...
- self.setValue(targetProject.getOutputAt(0).getPath())
- elif targetProject.getOutputCount()>1:
- # Don't know which....
- responsibleParty.addError( \
+ self.setValueFromOutput(candidates[0], reference)
+ elif len(candidates) > 1:
+ # Don't know which....
+ responsibleParty.addError( \
("Multiple outputs defined by project %s; " + \
- "an id attribute is required to select the one you want") % \
- (targetProject.getName()))
+ "an id attribute is required to select " \
+ + "the one you want") % \
+ (targetProject.getName()))
else:
- responsibleParty.addError( \
+ responsibleParty.addError( \
('Project %s defines no outputs') % \
- (targetProject.getName()))
+ (targetProject.getName()))
else:
- responsibleParty.addError('No project specified.')
-
+ responsibleParty.addError('No project specified.')
+
elif self.hasDomAttribute('path'):
# If a property on a project..
- if not parent==workspace:
- relativeProject=None
+ if not parent == workspace:
+ relativeProject = None
# If on a referenced project
if self.hasDomAttribute('project'):
- project=self.getDomAttributeValue('project')
+ project = self.getDomAttributeValue('project')
if not workspace.hasProject(project):
- responsibleParty.addError('Cannot resolve relative to *unknown* [' + project + '] for ' + \
- self.getName())
- else:
+ responsibleParty.addError('Cannot resolve relative ' \
+ + ' to *unknown* [' + \
+ project + '] for ' + \
+ self.getName())
+ else:
# Relative to referenced project
- relativeProject=workspace.getProject(project)
+ relativeProject = workspace.getProject(project)
else:
# Relative to this project...
- relativeProject=responsibleParty
-
- if relativeProject:
- # Path relative to module's srcdir (doesn't work in workspace)
- path=self.getDomAttributeValue('path')
- self.value=os.path.abspath(os.path.join( \
- relativeProject.getModule().getWorkingDirectory(),
+ relativeProject = responsibleParty
+
+ if relativeProject:
+ # Path relative to module's srcdir (doesn't work
+ # in workspace)
+ path = self.getDomAttributeValue('path')
+ self.value = os.path.abspath(os.path.join( \
+ relativeProject.getModule().getWorkingDirectory(),
path))
else:
responsibleParty.addError( \
- 'Can\'t have path on property on workspace: ' + self.getName())
+ 'Can\'t have path on property on workspace: ' \
+ + self.getName())
else:
# Nothing set, allow blank
blankOk = True
-
+
#
# Do we have a value yet?
#
- if not blankOk and isinstance(self.value,NoneType):
- responsibleParty.addError('Unhandled Property: ' + self.getName() + ' on: ' + str(parent))
- self.value='*Unset*'
-
+ if not blankOk and isinstance(self.value, NoneType):
+ responsibleParty.addError('Unhandled Property: ' \
+ + self.getName() + ' on: ' \
+ + str(parent))
+ self.value = '*Unset*'
+
self.setComplete(True)
-
- def dump(self, indent=0, output=sys.stdout):
+
+ def setValueFromOutput(self, output, reference):
+ """
+ set value to path or name of output depending on reference attribute
+ """
+ if reference == 'jarpath' or reference == 'outputpath':
+ self.setValue(output.getPath())
+ else:
+ self.setValue(output.getName())
+
+ def type_matches(self, output):
+ """
+ Does the output's type match the outputtype attribute - if any?
+ """
+ has_output_type = self.hasDomAttribute('outputtype')
+ output_type = self.getDomAttributeValue('outputtype')
+ return (has_output_type and output.getType() == output_type) \
+ or \
+ (not has_output_type and output.is_jar())
+
+ def dump(self, indent = 0, output = sys.stdout):
""" Display the property """
- output.write(getIndent(indent)+'Property: ' + self.getName() + ' ' + self.getValue()+ '\n')
+ output.write(getIndent(indent) + 'Property: ' + self.getName() + ' ' \
+ + self.getValue() + '\n')
class PropertySet(Ownable):
""" Can hold properties """
- def __init__(self,owner,properties=None):
-
- Ownable.__init__(self,owner)
-
- self.properties={}
-
+ def __init__(self, owner, properties = None):
+
+ Ownable.__init__(self, owner)
+
+ self.properties = {}
+
# Any starting properties..
if properties:
- self.properties=properties
-
+ self.properties = properties
+
def __del__(self):
Ownable.__del__(self)
-
- def addProperty(self,property):
- self.properties[property.getName()]=property
-
- def setProperty(self,name,value):
- self.properties[name]=Property(name,value)
-
- def getPropertyValue(self,name):
+
+ def addProperty(self, property):
+ self.properties[property.getName()] = property
+
+ def setProperty(self, name, value):
+ self.properties[name] = Property(name, value)
+
+ def getPropertyValue(self, name):
return self.properties[name].getValue()
-
- def getProperty(self,name):
+
+ def getProperty(self, name):
return self.properties[name]
-
+
def hasProperties(self):
- if self.properties: return True
+ if self.properties:
+ return True
return False
-
+
def getProperties(self):
"""
Get a list of all the property objects
"""
return self.properties.values()
-
- def importProperty(self,pdom):
+
+ def importProperty(self, pdom):
"""
- Import a project from the DOM
+ Import a project from the DOM
"""
- property=None
-
- if hasDomAttribute(pdom,'name'):
- name=getDomAttributeValue(pdom,'name')
- property=Property(name,pdom,self.getOwner())
+ property = None
+
+ if hasDomAttribute(pdom, 'name'):
+ name = getDomAttributeValue(pdom, 'name')
+ property = Property(name, pdom, self.getOwner())
self.addProperty(property)
else:
- self.getOwner().addError('Property without name : ' + pdom.toprettyxml())
-
+ self.getOwner().addError('Property without name : ' \
+ + pdom.toprettyxml())
+
return property
-
- def completeProperties(self,workspace):
+
+ def completeProperties(self, workspace):
for property in self.getProperties():
- property.complete(self.getOwner(),workspace)
-
- def dump(self, indent=0, output=sys.stdout):
+ property.complete(self.getOwner(), workspace)
+
+ def dump(self, indent = 0, output = sys.stdout):
""" Display the properties """
for property in self.getProperties():
- property.dump(indent+1,output)
+ property.dump(indent + 1, output)
class PropertyContainer:
"""
-
+
Can hold two sets of properties (normal and system)
-
+
Note: This depends upon the 'user' class being 'Ownable'.
-
+
"""
- def __init__(self,properties=None,sysproperties=None):
- self.properties=PropertySet(self, properties)
- self.sysproperties=PropertySet(self, sysproperties)
-
+ def __init__(self, properties = None, sysproperties = None):
+ self.properties = PropertySet(self, properties)
+ self.sysproperties = PropertySet(self, sysproperties)
+
def hasProperties(self):
- if self.properties: return True
+ if self.properties:
+ return True
return False
-
+
def getProperties(self):
return self.properties.getProperties()
-
+
def hasSysProperties(self):
- if self.sysproperties: return True
+ if self.sysproperties:
+ return True
return False
-
+
def getSysProperties(self):
return self.sysproperties.getProperties()
-
- def importProperty(self,domproperty):
+
+ def importProperty(self, domproperty):
self.properties.importProperty(domproperty)
-
- def importSysProperty(self,domproperty):
+
+ def importSysProperty(self, domproperty):
self.sysproperties.importProperty(domproperty)
-
- def importProperties(self,dom):
+
+ def importProperties(self, dom):
""" Import all properties (from DOM to model). """
- for element in getDomChildIterator(dom,'property'):
+ for element in getDomChildIterator(dom, 'property'):
self.importProperty(element)
-
- for element in getDomChildIterator(dom,'sysproperty'):
+
+ for element in getDomChildIterator(dom, 'sysproperty'):
self.importSysProperty(element)
-
- def completeProperties(self,workspace=None):
- # The only entity not to pass the workspace,
+
+ def completeProperties(self, workspace = None):
+ # The only entity not to pass the workspace,
# can be the workspace itself.
- if not workspace: workspace=self
+ if not workspace:
+ workspace = self
# Import normal and system
self.properties.completeProperties(workspace)
self.sysproperties.completeProperties(workspace)
-
- def dump(self, indent=0, output=sys.stdout):
+
+ def dump(self, indent = 0, output = sys.stdout):
""" Display the properties """
- self.properties.dump(indent,output)
- self.sysproperties.dump(indent,output)
-
+ self.properties.dump(indent, output)
+ self.sysproperties.dump(indent, output)
+
Propchange: gump/live/python/gump/core/update/bzr.py
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Jul 5 04:04:28 2010
@@ -1 +1 @@
-/gump/trunk/python/gump/core/update/bzr.py:815848,953630-954169,955387,955837,956771,957107,957408,958453,958915,959344,959847
+/gump/trunk/python/gump/core/update/bzr.py:815848,953630-954169,955387,955837,956771,957107,957408,958453,958915,959344,959847,960295,960297,960300,960303
Propchange: gump/live/python/gump/core/update/darcs.py
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Jul 5 04:04:28 2010
@@ -1 +1 @@
-/gump/trunk/python/gump/core/update/darcs.py:815848,953630-954169,955387,955837,956771,957107,957408,958453,958915,959344,959847
+/gump/trunk/python/gump/core/update/darcs.py:815848,953630-954169,955387,955837,956771,957107,957408,958453,958915,959344,959847,960295,960297,960300,960303
Propchange: gump/live/python/gump/core/update/hg.py
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Jul 5 04:04:28 2010
@@ -1 +1 @@
-/gump/trunk/python/gump/core/update/hg.py:815848,953630-954169,955387,955837,956771,957107,957408,958453,958915,959344,959847
+/gump/trunk/python/gump/core/update/hg.py:815848,953630-954169,955387,955837,956771,957107,957408,958453,958915,959344,959847,960295,960297,960300,960303