Package pysys :: Package xml :: Module project
[hide private]
[frames] | no frames]

Source Code for Module pysys.xml.project

  1  #!/usr/bin/env python 
  2  # PySys System Test Framework, Copyright (C) 2006-2013  M.B.Grieve 
  3   
  4  # This library is free software; you can redistribute it and/or 
  5  # modify it under the terms of the GNU Lesser General Public 
  6  # License as published by the Free Software Foundation; either 
  7  # version 2.1 of the License, or (at your option) any later version. 
  8   
  9  # This library is distributed in the hope that it will be useful, 
 10  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 12  # Lesser General Public License for more details. 
 13   
 14  # You should have received a copy of the GNU Lesser General Public 
 15  # License along with this library; if not, write to the Free Software 
 16  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 
 17   
 18  # Contact: moraygrieve@users.sourceforge.net 
 19   
 20  import os, os.path, sys, string, logging, time, xml.dom.minidom 
 21   
 22  from pysys.constants import * 
 23   
 24  log = logging.getLogger('pysys.xml.project') 
 25   
 26  DTD=''' 
 27  <!DOCTYPE pysysproject [ 
 28  <!ELEMENT pysysproject (property*, path*, runner?, writers?, formatters?) > 
 29  <!ELEMENT property (#PCDATA)> 
 30  <!ELEMENT path (#PCDATA)> 
 31  <!ELEMENT runner (#PCDATA)> 
 32  <!ELEMENT formatters (formatter+) > 
 33  <!ELEMENT formatter (#PCDATA) > 
 34  <!ELEMENT writers (writer+) > 
 35  <!ELEMENT writer (property*) > 
 36  <!ATTLIST property root CDATA #IMPLIED> 
 37  <!ATTLIST property environment CDATA #IMPLIED> 
 38  <!ATTLIST property osfamily CDATA #IMPLIED> 
 39  <!ATTLIST property file CDATA #IMPLIED> 
 40  <!ATTLIST property name CDATA #IMPLIED> 
 41  <!ATTLIST property value CDATA #IMPLIED> 
 42  <!ATTLIST property default CDATA #IMPLIED> 
 43  <!ATTLIST path value CDATA #REQUIRED> 
 44  <!ATTLIST path relative CDATA #IMPLIED> 
 45  <!ATTLIST runner classname CDATA #REQUIRED> 
 46  <!ATTLIST runner module CDATA #REQUIRED> 
 47  <!ATTLIST formatter name CDATA #REQUIRED> 
 48  <!ATTLIST formatter messagefmt CDATA #REQUIRED> 
 49  <!ATTLIST formatter datefmt CDATA #REQUIRED> 
 50  <!ATTLIST writer classname CDATA #REQUIRED> 
 51  <!ATTLIST writer module CDATA #REQUIRED> 
 52  <!ATTLIST writer file CDATA #IMPLIED> 
 53  ]> 
 54  ''' 
 55   
 56  PROPERTY_EXPAND_ENV = "(?P<replace>\${%s.(?P<key>.*?)})" 
 57  PROPERTY_EXPAND = "(?P<replace>\${(?P<key>.*?)})" 
 58  PROPERTY_FILE = "(?P<name>^.*)=(?P<value>.*)$" 
 59   
 60   
61 -class XMLProjectParser:
62 - def __init__(self, dirname, file):
63 self.dirname = dirname 64 self.xmlfile = os.path.join(dirname, file) 65 self.rootdir = 'root' 66 self.environment = 'env' 67 self.osfamily = 'osfamily' 68 self.properties = {self.rootdir:self.dirname, self.osfamily:OSFAMILY} 69 70 if not os.path.exists(self.xmlfile): 71 raise Exception, "Unable to find supplied project file \"%s\"" % self.xmlfile 72 73 try: 74 self.doc = xml.dom.minidom.parse(self.xmlfile) 75 except: 76 raise Exception, sys.exc_info()[1] 77 else: 78 if self.doc.getElementsByTagName('pysysproject') == []: 79 raise Exception, "No <pysysproject> element supplied in project file" 80 else: 81 self.root = self.doc.getElementsByTagName('pysysproject')[0]
82 83 86 87
88 - def getProperties(self):
89 propertyNodeList = self.root.getElementsByTagName('property') 90 91 for propertyNode in propertyNodeList: 92 if propertyNode.hasAttribute("environment"): 93 self.environment = propertyNode.getAttribute("environment") 94 95 elif propertyNode.hasAttribute("root"): 96 self.properties.pop(self.rootdir, "") 97 self.rootdir = propertyNode.getAttribute("root") 98 self.properties[self.rootdir] = self.dirname 99 100 elif propertyNode.hasAttribute("osfamily"): 101 self.properties.pop(self.osfamily, "") 102 self.osfamily = propertyNode.getAttribute("osfamily") 103 self.properties[self.osfamily] = OSFAMILY 104 105 elif propertyNode.hasAttribute("file"): 106 file = self.expandFromProperty(propertyNode.getAttribute("file"), propertyNode.getAttribute("default")) 107 self.getPropertiesFromFile(os.path.join(self.dirname, file)) 108 109 elif propertyNode.hasAttribute("name"): 110 name = propertyNode.getAttribute("name") 111 value = self.expandFromEnvironent(propertyNode.getAttribute("value"), propertyNode.getAttribute("default")) 112 self.properties[name] = self.expandFromProperty(value, propertyNode.getAttribute("default")) 113 114 return self.properties
115 116
117 - def getPropertiesFromFile(self, file):
118 if os.path.exists(file): 119 try: 120 fp = open(file, "r") 121 except: 122 pass 123 else: 124 for line in fp.readlines(): 125 regex = re.compile(PROPERTY_FILE, re.M) 126 if regex.search(line) is not None: 127 name = re.match(regex, line).group('name') 128 value = re.match(regex, line).group('value') 129 value = self.expandFromProperty(value, "") 130 self.properties[name.strip()] = value.strip()
131 132
133 - def expandFromEnvironent(self, value, default):
134 regex = re.compile(PROPERTY_EXPAND_ENV%self.environment, re.M) 135 while regex.search(value) is not None: 136 matches = regex.findall(value) 137 for m in matches: 138 try: 139 insert = os.environ[m[1]] 140 except : 141 insert = default 142 value = value.replace(m[0], insert) 143 return value
144 145
146 - def expandFromProperty(self, value, default):
147 regex = re.compile(PROPERTY_EXPAND, re.M) 148 while regex.search(value) is not None: 149 matches = regex.findall(value) 150 for m in matches: 151 try: 152 insert = self.properties[m[1]] 153 except : 154 insert = default 155 value = value.replace(m[0], insert) 156 return value
157 158
159 - def getRunnerDetails(self):
160 try: 161 runnerNodeList = self.root.getElementsByTagName('runner')[0] 162 return [runnerNodeList.getAttribute('classname'), runnerNodeList.getAttribute('module')] 163 except: 164 return DEFAULT_RUNNER
165 166
167 - def setFormatters(self, formatters):
168 formattersNodeList = self.root.getElementsByTagName('formatters') 169 if formattersNodeList == []: return 170 171 try: 172 formatterNodeList = formattersNodeList[0].getElementsByTagName('formatter') 173 if formatterNodeList != []: 174 for formatterNode in formatterNodeList: 175 try: 176 datefmt = '' 177 name = formatterNode.getAttribute('name') 178 messagefmt = formatterNode.getAttribute('messagefmt') 179 if formatterNode.hasAttribute('datefmt'): datefmt = formatterNode.getAttribute('datefmt') 180 setattr(formatters, name, logging.Formatter(messagefmt, datefmt)) 181 except: 182 pass 183 return 184 except: 185 return
186 187
188 - def getWriterDetails(self):
189 writersNodeList = self.root.getElementsByTagName('writers') 190 if writersNodeList == []: return [DEFAULT_WRITER] 191 192 try: 193 writers = [] 194 writerNodeList = writersNodeList[0].getElementsByTagName('writer') 195 if writerNodeList != []: 196 for writerNode in writerNodeList: 197 try: 198 file = writerNode.getAttribute('file') if writerNode.hasAttribute('file') else None 199 writer = [writerNode.getAttribute('classname'), writerNode.getAttribute('module'), file, {}] 200 except: 201 pass 202 else: 203 propertyNodeList = writerNode.getElementsByTagName('property') 204 for propertyNode in propertyNodeList: 205 try: 206 name = propertyNode.getAttribute("name") 207 value = self.expandFromEnvironent(propertyNode.getAttribute("value"), propertyNode.getAttribute("default")) 208 writer[3][name] = self.expandFromProperty(value, propertyNode.getAttribute("default")) 209 except: 210 pass 211 writers.append(writer) 212 else: 213 writers.append(DEFAULT_WRITER) 214 return writers 215 except: 216 return [DEFAULT_WRITER]
217 218
219 - def addToPath(self):
220 pathNodeList = self.root.getElementsByTagName('path') 221 222 for pathNode in pathNodeList: 223 try: 224 value = pathNode.getAttribute("value") 225 relative = pathNode.getAttribute("relative") 226 227 if relative == "true": value = os.path.join(self.dirname, value) 228 sys.path.append(os.path.normpath(value)) 229 230 except: 231 pass
232 233
234 - def writeXml(self):
235 f = open(self.xmlfile, 'w') 236 f.write(self.doc.toxml()) 237 f.close()
238