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-2016  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?, maker?, writers?, formatters?) > 
 29  <!ELEMENT property (#PCDATA)> 
 30  <!ELEMENT path (#PCDATA)> 
 31  <!ELEMENT runner (#PCDATA)> 
 32  <!ELEMENT maker (#PCDATA)> 
 33  <!ELEMENT formatters (formatter+) > 
 34  <!ELEMENT formatter (#PCDATA) > 
 35  <!ELEMENT writers (writer+) > 
 36  <!ELEMENT writer (property*) > 
 37  <!ATTLIST property root CDATA #IMPLIED> 
 38  <!ATTLIST property environment CDATA #IMPLIED> 
 39  <!ATTLIST property osfamily CDATA #IMPLIED> 
 40  <!ATTLIST property file CDATA #IMPLIED> 
 41  <!ATTLIST property name CDATA #IMPLIED> 
 42  <!ATTLIST property value CDATA #IMPLIED> 
 43  <!ATTLIST property default CDATA #IMPLIED> 
 44  <!ATTLIST path value CDATA #REQUIRED> 
 45  <!ATTLIST path relative CDATA #IMPLIED> 
 46  <!ATTLIST runner classname CDATA #REQUIRED> 
 47  <!ATTLIST runner module CDATA #REQUIRED> 
 48  <!ATTLIST maker classname CDATA #REQUIRED> 
 49  <!ATTLIST maker module CDATA #REQUIRED> 
 50  <!ATTLIST formatter name CDATA #REQUIRED> 
 51  <!ATTLIST formatter messagefmt CDATA #REQUIRED> 
 52  <!ATTLIST formatter datefmt CDATA #REQUIRED> 
 53  <!ATTLIST writer classname CDATA #REQUIRED> 
 54  <!ATTLIST writer module CDATA #REQUIRED> 
 55  <!ATTLIST writer file CDATA #IMPLIED> 
 56  ]> 
 57  ''' 
 58   
 59  PROPERTY_EXPAND_ENV = "(?P<replace>\${%s.(?P<key>.*?)})" 
 60  PROPERTY_EXPAND = "(?P<replace>\${(?P<key>.*?)})" 
 61  PROPERTY_FILE = "(?P<name>^.*)=(?P<value>.*)$" 
 62   
 63   
64 -class XMLProjectParser:
65 - def __init__(self, dirname, file):
66 self.dirname = dirname 67 self.xmlfile = os.path.join(dirname, file) 68 self.rootdir = 'root' 69 self.environment = 'env' 70 self.osfamily = 'osfamily' 71 self.properties = {self.rootdir:self.dirname, self.osfamily:OSFAMILY} 72 73 if not os.path.exists(self.xmlfile): 74 raise Exception, "Unable to find supplied project file \"%s\"" % self.xmlfile 75 76 try: 77 self.doc = xml.dom.minidom.parse(self.xmlfile) 78 except: 79 raise Exception, sys.exc_info()[1] 80 else: 81 if self.doc.getElementsByTagName('pysysproject') == []: 82 raise Exception, "No <pysysproject> element supplied in project file" 83 else: 84 self.root = self.doc.getElementsByTagName('pysysproject')[0]
85 86 89 90
91 - def getProperties(self):
92 propertyNodeList = self.root.getElementsByTagName('property') 93 94 for propertyNode in propertyNodeList: 95 if propertyNode.hasAttribute("environment"): 96 self.environment = propertyNode.getAttribute("environment") 97 98 elif propertyNode.hasAttribute("root"): 99 self.properties.pop(self.rootdir, "") 100 self.rootdir = propertyNode.getAttribute("root") 101 self.properties[self.rootdir] = self.dirname 102 103 elif propertyNode.hasAttribute("osfamily"): 104 self.properties.pop(self.osfamily, "") 105 self.osfamily = propertyNode.getAttribute("osfamily") 106 self.properties[self.osfamily] = OSFAMILY 107 108 elif propertyNode.hasAttribute("file"): 109 file = self.expandFromProperty(propertyNode.getAttribute("file"), propertyNode.getAttribute("default")) 110 self.getPropertiesFromFile(os.path.join(self.dirname, file)) 111 112 elif propertyNode.hasAttribute("name"): 113 name = propertyNode.getAttribute("name") 114 value = self.expandFromEnvironent(propertyNode.getAttribute("value"), propertyNode.getAttribute("default")) 115 self.properties[name] = self.expandFromProperty(value, propertyNode.getAttribute("default")) 116 117 return self.properties
118 119
120 - def getPropertiesFromFile(self, file):
121 if os.path.exists(file): 122 try: 123 fp = open(file, "r") 124 except: 125 pass 126 else: 127 for line in fp.readlines(): 128 regex = re.compile(PROPERTY_FILE, re.M) 129 if regex.search(line) is not None: 130 name = re.match(regex, line).group('name') 131 value = re.match(regex, line).group('value') 132 value = self.expandFromProperty(value, "") 133 self.properties[name.strip()] = value.strip()
134 135
136 - def expandFromEnvironent(self, value, default):
137 regex = re.compile(PROPERTY_EXPAND_ENV%self.environment, re.M) 138 while regex.search(value) is not None: 139 matches = regex.findall(value) 140 for m in matches: 141 try: 142 insert = os.environ[m[1]] 143 except : 144 insert = default 145 value = value.replace(m[0], insert) 146 return value
147 148
149 - def expandFromProperty(self, value, default):
150 regex = re.compile(PROPERTY_EXPAND, re.M) 151 while regex.search(value) is not None: 152 matches = regex.findall(value) 153 for m in matches: 154 try: 155 insert = self.properties[m[1]] 156 except : 157 insert = default 158 value = value.replace(m[0], insert) 159 return value
160 161
162 - def getRunnerDetails(self):
163 try: 164 runnerNodeList = self.root.getElementsByTagName('runner')[0] 165 return [runnerNodeList.getAttribute('classname'), runnerNodeList.getAttribute('module')] 166 except: 167 return DEFAULT_RUNNER
168 169
170 - def getMakerDetails(self):
171 try: 172 makerNodeList = self.root.getElementsByTagName('maker')[0] 173 return [makerNodeList.getAttribute('classname'), makerNodeList.getAttribute('module')] 174 except: 175 return DEFAULT_MAKER
176 177
178 - def setFormatters(self, formatters):
179 formattersNodeList = self.root.getElementsByTagName('formatters') 180 if formattersNodeList == []: return 181 182 try: 183 formatterNodeList = formattersNodeList[0].getElementsByTagName('formatter') 184 if formatterNodeList != []: 185 for formatterNode in formatterNodeList: 186 try: 187 datefmt = '' 188 name = formatterNode.getAttribute('name') 189 messagefmt = formatterNode.getAttribute('messagefmt') 190 if formatterNode.hasAttribute('datefmt'): datefmt = formatterNode.getAttribute('datefmt') 191 setattr(formatters, name, logging.Formatter(messagefmt, datefmt)) 192 except: 193 pass 194 return 195 except: 196 return
197 198
199 - def getWriterDetails(self):
200 writersNodeList = self.root.getElementsByTagName('writers') 201 if writersNodeList == []: return [DEFAULT_WRITER] 202 203 try: 204 writers = [] 205 writerNodeList = writersNodeList[0].getElementsByTagName('writer') 206 if writerNodeList != []: 207 for writerNode in writerNodeList: 208 try: 209 file = writerNode.getAttribute('file') if writerNode.hasAttribute('file') else None 210 writer = [writerNode.getAttribute('classname'), writerNode.getAttribute('module'), file, {}] 211 except: 212 pass 213 else: 214 propertyNodeList = writerNode.getElementsByTagName('property') 215 for propertyNode in propertyNodeList: 216 try: 217 name = propertyNode.getAttribute("name") 218 value = self.expandFromEnvironent(propertyNode.getAttribute("value"), propertyNode.getAttribute("default")) 219 writer[3][name] = self.expandFromProperty(value, propertyNode.getAttribute("default")) 220 except: 221 pass 222 writers.append(writer) 223 else: 224 writers.append(DEFAULT_WRITER) 225 return writers 226 except: 227 return [DEFAULT_WRITER]
228 229
230 - def addToPath(self):
231 pathNodeList = self.root.getElementsByTagName('path') 232 233 for pathNode in pathNodeList: 234 try: 235 value = self.expandFromEnvironent(pathNode.getAttribute("value"), "") 236 value = self.expandFromProperty(value, "") 237 relative = pathNode.getAttribute("relative") 238 239 if relative == "true": value = os.path.join(self.dirname, value) 240 sys.path.append(os.path.normpath(value)) 241 242 except: 243 pass
244 245
246 - def writeXml(self):
247 f = open(self.xmlfile, 'w') 248 f.write(self.doc.toxml()) 249 f.close()
250