[Modeling-cvs] ProjectModeling/Modeling/ModelMasons ModelMason.py,1.6,1.7 PyModelMason.py,1.8,1.9
Status: Abandoned
Brought to you by:
sbigaret
|
From: <sbi...@us...> - 2003-05-26 15:45:21
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons
In directory sc8-pr-cvs1:/tmp/cvs-serv21164/ModelMasons
Modified Files:
ModelMason.py PyModelMason.py
Log Message:
Merged changes from brch-0_9pre6-1-ModelMasons_base_generation_scheme to trunk
Index: ModelMason.py
===================================================================
RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/ModelMason.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** ModelMason.py 20 Apr 2003 14:16:42 -0000 1.6
--- ModelMason.py 26 May 2003 15:44:48 -0000 1.7
***************
*** 24,30 ****
"""
- ModelMason
! Documentation forthcoming. See PyModelMason for an example of use.
CVS information
--- 24,34 ----
"""
! ModelMason contains the base class for every ''mason'' and is of no interest
! except if you plan to design a new module to generate code/files from a Model.
!
! When this is the case, the class' documentation indicate the rules that should
! be respected to ensure easy integration with the framework's tools such as the
! script mdl_generate_python_code or the ZModeler.
CVS information
***************
*** 40,46 ****
class ModelMason:
def __init__(self, model, rootPath, concreteBuilder, bricksDir,
! verbose_mode=0):
"""
Initializes the ModelMason so that the built files are based on the
--- 44,84 ----
class ModelMason:
+ """
+ This class should be the base class for every masons.
+
+ When subclassing this class, you should take care of:
+
+ - call ModelMason.__init__() if it is overridden
+
+ - if the subclass needs to change/create sth. on the filesystem, it *must*
+ check whether 'fake_mode' is set: if it is set, absolutely no changes
+ should be made on the disk.
+
+ Methods createEmptyFile(), createFileFromTemplate(), copyFile() and
+ build_package() can be used without this precaution since they already
+ check 'self.fake_mode' before making any changes on the disk.
+
+ - call log() to record any action relative to the generation (such as the
+ creation of a file). Please note that you should be ready to log these
+ actions even when fake_mode is set. For example, suppose 'file.py'
+ should be generated but not overwritten; if the file does not exist
+ you'd log('Creating file file.py'), and if it exists you'd log('File.py
+ exists, skipping') whether fake_mode is set or not. This makes it
+ possible for the user to see what would happen whene (re)generating the
+ code without actually making the changes.
+
+ Following these rules makes it easy to integrate a custom ''mason'' into
+ the script mdl_generate_python_code and the ZModeler.
+
+ All subclasses need to override build() and put there the logic which
+ generates the code. You will probably override method tmpl_namespace() as
+ well (see its documentation for details).
+
+ You can also refer to PyModelMason for an example of use.
+
+ """
def __init__(self, model, rootPath, concreteBuilder, bricksDir,
! verbose_mode=0, fake_mode=0):
"""
Initializes the ModelMason so that the built files are based on the
***************
*** 64,67 ****
--- 102,108 ----
generating the files
+ fake_mode -- if true, do not create or change any file, just report what
+ would be done
+
Subclasses may decide to supply a default value for the product's base
directory when parameter 'rootPath' is not supplied.
***************
*** 75,79 ****
bricksDir)
self.verbose_mode=verbose_mode
!
def fullPathForBrick(self, aBrick):
"""
--- 116,121 ----
bricksDir)
self.verbose_mode=verbose_mode
! self.fake_mode=fake_mode
!
def fullPathForBrick(self, aBrick):
"""
***************
*** 98,103 ****
return
self.log('Creating empty file %s\n'%filename)
! f = open(filename,"w")
! f.close()
def copyFile(self, templateFilename, destinationFilename,overwrite=0):
--- 140,146 ----
return
self.log('Creating empty file %s\n'%filename)
! if not self.fake_mode:
! f = open(filename,"w")
! f.close()
def copyFile(self, templateFilename, destinationFilename,overwrite=0):
***************
*** 113,121 ****
return
self.log('Creating file %s\n'%destinationFilename)
! _f1 = open(self.fullPathForGeneratedFile(destinationFilename),'w')
! _f2 = open(self.fullPathForBrick(templateFilename),'r')
! _f1.write(_f2.read())
! _f1.close()
! _f2.close()
_marker=[]
--- 156,165 ----
return
self.log('Creating file %s\n'%destinationFilename)
! if not self.fake_mode:
! _f1 = open(self.fullPathForGeneratedFile(destinationFilename),'w')
! _f2 = open(self.fullPathForBrick(templateFilename),'r')
! _f1.write(_f2.read())
! _f1.close()
! _f2.close()
_marker=[]
***************
*** 159,169 ****
namespace=self.fix_tmpl_namespace(namespace)
destFile = self.fullPathForGeneratedFile(destFile)
! if not overwrite and os.path.exists(destFile):
self.log("File %s exists, skipping\n"%destFile)
return
! self.log("Generating %s... " % destFile)
! f = open(destFile,'w')
! f.write("%s"%self.templateObjectForTemplate(template,namespace=namespace))
! self.log("done\n")
def build(self):
--- 203,220 ----
namespace=self.fix_tmpl_namespace(namespace)
destFile = self.fullPathForGeneratedFile(destFile)
! file_exists=os.path.exists(destFile)
! if not overwrite and file_exists:
self.log("File %s exists, skipping\n"%destFile)
return
! if not overwrite or (overwrite and not file_exists):
! self.log("Generating %s" % destFile)
! else:
! self.log("Overwriting %s" % destFile)
!
! if not self.fake_mode:
! f = open(destFile,'w')
! f.write("%s"%self.templateObjectForTemplate(template,namespace=namespace))
! self.log("... done")
! self.log('\n')
def build(self):
***************
*** 201,205 ****
{'model': self.model}
! Subclasses override this method to provide their own namespace
"""
return {'model': self.model}
--- 252,258 ----
{'model': self.model}
! Subclasses override this method to provide their own namespace. This
! namespace is the default one transmitted to the Cheetah template when no
! specific namespace is passed to method createFileFromTemplate().
"""
return {'model': self.model}
***************
*** 215,224 ****
for pack in string.split(self.model.packageName(), '.')[:-1]:
currentPath=os.path.join(currentPath, pack)
! self.log('Creating directory %s... '%currentPath)
! try:
! os.mkdir(currentPath)
! except: self.log('no\n')
! else: self.log('ok\n')
!
init=os.path.join(currentPath, '__init__.py')
if os.path.exists(init):
--- 268,279 ----
for pack in string.split(self.model.packageName(), '.')[:-1]:
currentPath=os.path.join(currentPath, pack)
! self.log('Creating directory %s'%currentPath)
! if not self.fake_mode:
! try:
! os.mkdir(currentPath)
! except: self.log('... no')
! else: self.log('... ok')
! self.log('\n')
!
init=os.path.join(currentPath, '__init__.py')
if os.path.exists(init):
***************
*** 226,237 ****
else:
self.log('Creating %s\n'%init)
! f=open(init,'w') ; f.close()
# Last, create self.packagePath
! self.log('Creating directory %s... '%self.packagePath)
! try:
! os.mkdir(self.packagePath)
! except: self.log('no\n')
! else: self.log('ok\n')
def log(self, msg):
--- 281,295 ----
else:
self.log('Creating %s\n'%init)
! if not self.fake_mode:
! f=open(init,'w') ; f.close()
# Last, create self.packagePath
! self.log('Creating directory %s'%self.packagePath)
! if not self.fake_mode:
! try:
! os.mkdir(self.packagePath)
! except: self.log('... no')
! else: self.log('... ok')
! self.log('\n')
def log(self, msg):
Index: PyModelMason.py
===================================================================
RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/PyModelMason.py,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** PyModelMason.py 20 Apr 2003 16:10:39 -0000 1.8
--- PyModelMason.py 26 May 2003 15:44:48 -0000 1.9
***************
*** 24,31 ****
"""
! PyModelMason
! Documentation forthcoming
CVS information
--- 24,45 ----
"""
! PyModelMason generates the python package, modules and classes described
! in a model, ready to be used w/ the modeling framework.
! Its templates are located in sub-package 'Python_bricks'. The generated code
! is compatible with python v2.1 and v2.2.
+ Given a model, it can generate the appropriate python code in two different
+ ways: the flat, or 'compact' scheme, and the 'base' scheme.
+
+ The former one generates all files within a single directory (namely: in
+ package model.packageName()), none of which (except the models) can be
+ overwritten when the code is regenerated.
+
+ The so-called 'base' scheme adds a subpackage 'MDL' within the generated
+ package. All files within MDL/ are ALWAYS overwritten when the python code is
+ regenerated, while others (in the root package) are never overwritten if they
+ exist. This is probably the one you want to use if your model changes often.
+
CVS information
***************
*** 40,48 ****
from Cheetah.Template import Template
! from Python_bricks import init,model,base_module,module_base,module_compact,setup_tmpl
class PyModelMason(ModelMason):
def __init__(self, model, rootPath=None, verbose_mode=0,
! generation_scheme='compact'):
"""
Initializes the ModelMason so that the built files are based on the
--- 54,118 ----
from Cheetah.Template import Template
! from Python_bricks import init,init_base,model,base_module,module_base,module_compact,setup_tmpl
!
! class InvalidModelError(Exception):
! "Raised by checkModelIsValid()"
! pass
!
! def checkModelIsValid(model, generation_scheme):
! """
! Checks that the supplied model is valid for a given python-code generation
! scheme:
!
! - if 'generation_scheme' is 'compact', all models are valid,
!
! - if 'generation_scheme' is 'base', the model is valid iff a class/entity does
! not share the same module than any of its subclasses
!
! Parameters:
!
! model -- a instance of Modeling.Model.Model
!
! generation_scheme -- either 'compact' or 'base'
!
! Returns: None
!
! Raises InvalidModelError if the model is invalid.
!
! Note: this is NOT validation of the model itself (responsability of
! Modeling.ModelValidation)
!
! """
! if generation_scheme=='compact': return
! if generation_scheme=='base':
!
! # Build ordered list of entities
! oe=[]
! entities=list(model.entities())
! entities_processed=[]
! for entity in [e for e in entities if not e.parentEntity()]:
! oe.append(entity)
! entities_processed.append(entity.name())
! entities.remove(entity)
! while entities:
! es=[e for e in entities if e.parentEntity().name() in entities_processed]
! for entity in es:
! entities.remove(entity)
! entities_processed.append(entity.name())
! oe.append(entity)
! # check every parent against it subentities
! for e in oe:
! parent_moduleName=e.moduleName()
! subs=e.allSubEntities()
! for sub in subs:
! if sub.moduleName()==parent_moduleName:
! raise InvalidModelError, "Model is invalid wrt the 'base' generation scheme: entity '%s' and its subentity '%s' share the same moduleName.\nEither correct this or use the 'compact' generation scheme"%(e.name(), sub.name())
! else:
! raise ValueError, "Invalid value for 'generation_scheme' (%s), should be either 'base' or 'compact'"%use_scheme
class PyModelMason(ModelMason):
+ "See the module's documentation for details"
def __init__(self, model, rootPath=None, verbose_mode=0,
! generation_scheme='compact', fake_mode=0):
"""
Initializes the ModelMason so that the built files are based on the
***************
*** 51,71 ****
Parameters:
! model --
! rootPath --
! verbode_mode --
use_scheme -- 'compact' or 'base'
"""
import Modeling
if generation_scheme not in ('compact', 'base'):
raise ValueError,"Parameter generation_scheme can be either 'compact' or 'base'"
ModelMason.__init__(self, model, rootPath,
Modeling.ModelMasons.PyModelMason, 'Python_bricks',
! verbose_mode)
self._entities=[] # used during build
self.generation_scheme=generation_scheme
def tmpl_namespace(self):
--- 121,145 ----
Parameters:
! model -- see ModelMason.__init__()
! rootPath -- see ModelMason.__init__()
! verbode_mode -- see ModelMason.__init__()
use_scheme -- 'compact' or 'base'
+ fake_mode -- see ModelMason.__init__()
+
"""
import Modeling
if generation_scheme not in ('compact', 'base'):
raise ValueError,"Parameter generation_scheme can be either 'compact' or 'base'"
+ checkModelIsValid(model, generation_scheme)
ModelMason.__init__(self, model, rootPath,
Modeling.ModelMasons.PyModelMason, 'Python_bricks',
! verbose_mode, fake_mode)
self._entities=[] # used during build
self.generation_scheme=generation_scheme
+ self.base_dir=generation_scheme=='base' and 'MDL' or ''
def tmpl_namespace(self):
***************
*** 77,80 ****
--- 151,156 ----
'model' : self.model,
'entities': self._entities,
+ 'base_dir': self.base_dir,
+ 'entitiesSet': self.entitiesSet,
}
return nameSpace
***************
*** 83,86 ****
--- 159,184 ----
def build(self):
"-"
+ #-----------------------------------------------------------------
+ def create_model_files(self, xml_path, py_path):
+ # model_<modelName>.xml
+ self.log('Generating %s'%xml_path)
+ if not self.fake_mode:
+ self.model.saveModelAsXMLFile(xml_path)
+ self.log('... done')
+ self.log('\n')
+ # model_<modelName>.py
+ if not self.fake_mode:
+ xml=open(xml_path)
+ modelStr=xml.read()
+ xml.close()
+ else:
+ modelStr='fake'
+ self.createFileFromTemplate(model.model(),
+ py_path,
+ namespace={'model_str':modelStr},
+ overwrite=1)
+ del modelStr
+ #-----------------------------------------------------------------
+
# Build as many directories with __init__.py as needed
self.build_package()
***************
*** 93,120 ****
self.createEmptyFile("DEPENDENCIES.txt",overwrite=0)
- # model_<modelName>.xml
- modelFileName='model_'+self.model.name()+'.xml'
- modelFileName=self.fullPathForGeneratedFile(modelFileName)
- self.log('Generating %s... '%modelFileName)
- self.model.saveModelAsXMLFile(modelFileName)
- self.log('done\n')
-
- # model_<modelName>.py
- xml=open(modelFileName)
- modelStr=xml.read()
- xml.close()
- self.createFileFromTemplate(model.model(),
- "model_%s.py"%self.model.name(),
- namespace={'model_str':modelStr},
- overwrite=1)
- del modelStr
-
# package's __init__.py
self.createFileFromTemplate(init.init(),"__init__.py",overwrite=0)
# setup.py
! self.createFileFromTemplate(setup_tmpl.setup_tmpl(),"setup.py")
# COMPACT generation scheme
if self.generation_scheme=='compact':
# modules
for self._entities in self.entitiesSet():
--- 191,206 ----
self.createEmptyFile("DEPENDENCIES.txt",overwrite=0)
# package's __init__.py
self.createFileFromTemplate(init.init(),"__init__.py",overwrite=0)
# setup.py
! self.createFileFromTemplate(setup_tmpl.setup_tmpl(),"setup.py",overwrite=0)
# COMPACT generation scheme
if self.generation_scheme=='compact':
+ # Create model files (.xml/.py)
+ xmlp=self.fullPathForGeneratedFile('model_'+self.model.name()+'.xml')
+ pyp="model_%s.py"%self.model.name()
+ create_model_files(self, xmlp, pyp)
+
# modules
for self._entities in self.entitiesSet():
***************
*** 126,137 ****
# BASE generation scheme
elif self.generation_scheme=='base':
! # create 'Base'
! #basePath=self.fullPathForGeneratedFile('Base')
! #self.log("Creating directory %s... "%basePath)
! #try:
! # os.mkdir(basePath)
! #except: self.log('no\n')
! #else: self.log('ok\n')
!
# modules
for self._entities in self.entitiesSet():
--- 212,232 ----
# BASE generation scheme
elif self.generation_scheme=='base':
! # create 'Base' and model files (.xml/.py)
! basePath=self.fullPathForGeneratedFile(self.base_dir)
! self.log("Creating directory %s"%basePath)
! if not self.fake_mode:
! try:
! os.mkdir(basePath)
! except: self.log('no\n')
! else: self.log('ok\n')
! self.createFileFromTemplate(init_base.init_base(),
! os.path.join(self.base_dir,"__init__.py"),
! overwrite=1)
!
! create_model_files(self,
! os.path.join(basePath,
! 'model_'+self.model.name()+'.xml'),
! os.path.join(self.base_dir,
! "model_%s.py"%self.model.name()))
# modules
for self._entities in self.entitiesSet():
***************
*** 141,144 ****
overwrite=0)
self.createFileFromTemplate(base_module.base_module(),
! "%sBase.py" % module_name,
overwrite=1)
--- 236,240 ----
overwrite=0)
self.createFileFromTemplate(base_module.base_module(),
! os.path.join(self.base_dir,
! "%s.py" % module_name),
overwrite=1)
|