Package inca :: Module VersionReporter
[hide private]
[frames] | no frames]

Source Code for Module inca.VersionReporter

  1  import os.path 
  2  import re 
  3   
  4  from inca.Reporter import Reporter 
  5   
6 -class VersionReporter(Reporter):
7 """VersionReporter - Convenience module for creating version reporters 8 9 from inca.VersionReporter import VersionReporter 10 reporter = VersionReporter() 11 command = 'somecommand -version' 12 pattern = '^version "(.*)"' 13 ... 14 reporter.setPackageName('packageX') 15 reporter.setVersionByExecutable(command, pattern) 16 reporter.printReporter() 17 18 or 19 20 reporter.setVersionByGptQuery('packageX') 21 22 or 23 24 reporter.setVersionByRpmQuery('packageX') 25 26 or 27 28 reporter->setPackageVersion('x.x.x') 29 30 or 31 32 for subpackage in subpackages: 33 reporter.setSubpackageVersion(subpackage, version) 34 35 This module is a subclass of Reporter that provides convenience methods 36 for creating version reporters. A version reporter reports this version 37 information for a package in the following schema (i.e., this is the body 38 of the Inca report): 39 40 <packageVersion> 41 <ID>packageX</ID> 42 <version>x.x.x</version> 43 </packageVersion> 44 45 or 46 47 <packageVersion> 48 <ID>packageX</ID> 49 <subpackage> 50 <ID>subpackageX</ID> 51 <version>x.x.x</version> 52 </subpackage> 53 <subpackage> 54 <ID>subpackageY</ID> 55 <version>x.x.x</version> 56 </subpackage> 57 </packageVersion> 58 59 Version information can be set using one of the basic methods 60 setPackageVersion (for the first example) or setSubpackageVersion (for the 61 second). In this case, the user retrieves a package's version information 62 directly and uses one of these two methods to report it. This module also 63 provides convenience methods that retrieve a package version using 64 conventional methods of querying version information. 65 """ 66
67 - def __init__(self, **attributes):
68 """Class constructor that returns a new VersionReporter object. The 69 constructor supports the following parameters in addition to those 70 supported by Reporter. 71 72 package_name 73 the name of the package for which a version is being determined; 74 default ''. 75 76 package_version 77 the version of the package. 78 """ 79 package_name = '' 80 if attributes.has_key('package_name'): 81 package_name = attributes['package_name'] 82 del attributes['package_name'] 83 package_version = None 84 if attributes.has_key('package_version'): 85 package_version = attributes['package_version'] 86 del attributes['package_version'] 87 Reporter.__init__(self, **attributes) 88 self.package_name = package_name 89 self.package_version = package_version 90 self.subpackage_versions = {} 91 self.addDependency('inca.VersionReporter')
92
93 - def getPackageName(self):
94 """Returns the name of the package.""" 95 return self.package_name
96
97 - def getPackageVersion(self):
98 """Returns the version of the package.""" 99 return self.package_version
100
101 - def getSubpackageNames(self):
102 """Returns a list of all the names of all subpackages with a set version.""" 103 return self.subpackage_versions.keys()
104
105 - def getSubpackageVersion(self, name):
106 """Returns the version of subpackage name.""" 107 result = None 108 if self.subpackage_versions.has_key(name): 109 result = self.subpackage_versions[name] 110 return result
111
112 - def reportBody(self):
113 """Constructs and returns the body of the reporter.""" 114 packageXml = [self.xmlElement('ID', 1, self.getPackageName())] 115 if self.getCompleted(): 116 if self.getPackageVersion() != None: 117 packageXml.append( 118 self.xmlElement('version', 1, self.getPackageVersion()) 119 ) 120 subpackages = self.getSubpackageNames() 121 subpackages.sort() 122 for subpackage in subpackages: 123 packageXml.append(self.xmlElement('subpackage', 0, 124 self.xmlElement('ID', 1, subpackage), 125 self.xmlElement('version', 1, self.getSubpackageVersion(subpackage)) 126 )) 127 return self.xmlElement('package', 0, *packageXml)
128
129 - def setPackageName(self, name):
130 """Set the name of the package.""" 131 self.package_name = name
132
133 - def setPackageVersion(self, version):
134 """Report the version of a package as version.""" 135 self.package_version = version 136 self.setCompleted(1)
137
138 - def setSubpackageVersion(self, name, version):
139 """Report the version of subpackage name as version.""" 140 self.subpackage_versions[name] = version 141 self.setCompleted(1)
142
143 - def setVersionByCompiledProgramOutput(self, **attrs):
144 """Retrieve the package version by compiling and running a program and 145 matching its output against a pattern. Returns 1 if successful, else 0. 146 The function recognizes the following parameter in addition to those 147 supported by the compiledProgramOutput method of Reporter: 148 149 pattern 150 pattern to search for in program output; default '(.+)' 151 """ 152 pattern = '(.+)' 153 if attrs.has_key('pattern'): 154 pattern = attrs['pattern'] 155 del attrs['pattern'] 156 output = self.compiledProgramOutput(**attrs) 157 if not output: 158 self.setCompleted(0) 159 self.setFailMessage('program compilation/execution failed') 160 else: 161 found = re.search(pattern, output) 162 if not found: 163 self.setCompleted(0) 164 self.setFailMessage("'" + pattern + "' not in '" + output + "'") 165 else: 166 self.setCompleted(1) 167 self.setPackageVersion(found.group(1)) 168 return self.getCompleted()
169
170 - def setVersionByExecutable(self, command, pattern=None, timeout=None):
171 """Retrieve package version information by executing command and greping 172 the output for pattern. command is the executable and argument string 173 to retrieve the version (e.g., command_name -version) and pattern is a 174 pattern containing one grouping (i.e., memory parentheses) to retrieve 175 the version from the output. pattern defaults to '([\d\.]+)' if not 176 specified. Fails if timeout is specified and command does not complete 177 within timeout seconds. Returns 1 if successful, else 0. 178 """ 179 if pattern == None: 180 pattern = r'([\d\.]+)' 181 output = self.loggedCommandOutput(command, timeout) 182 if not output or re.search('command not found', output): 183 self.setCompleted(0) 184 if not output: 185 self.setFailMessage('') 186 else: 187 self.setFailMessage(output) 188 else: 189 found = re.search(pattern, output) 190 if not found: 191 self.setCompleted(0) 192 self.setFailMessage("'" + pattern + "' not in '" + output + "'") 193 else: 194 version = None 195 for group in found.groups(): 196 if group != None: 197 version = group 198 if version != None: 199 self.setCompleted(1) 200 self.setPackageVersion(version) 201 else: 202 self.setCompleted(0) 203 self.setFailMessage("'" + pattern + "' not in '" + output + "'") 204 return self.getCompleted()
205
206 - def setVersionByFileContents(self, path, pattern=None):
207 """Retrieve the package version by grep'ing the file path for pattern. 208 pattern defaults to '([\d\.]+)' if not specified. Returns 1 if 209 successful, else 0. 210 """ 211 if pattern == None: 212 pattern = r'([\d\.]+)' 213 if not os.path.exists(path): 214 self.setCompleted(0) 215 self.setFailMessage("file '" + path + "' not present") 216 else: 217 input = open(path, 'r') 218 if not input: 219 self.setCompleted(0) 220 self.setFailMessage("file '" + path + "' is not readable") 221 else: 222 line = input.readline() 223 while line != None and not re.search(pattern, line): 224 line = input.readline() 225 input.close() 226 if line == None: 227 self.setCompleted(0) 228 self.setFailMessage("'"+pattern+"' not found in file '"+path+"'") 229 else: 230 self.setCompleted(1) 231 found = re.search(pattern, line) 232 self.setPackageVersion(found.group(1)) 233 return self.getCompleted()
234
235 - def setVersionByGptQuery(self, *prefixes):
236 """Set subpackage version information by querying GPT for packages prefixed 237 with any element of prefixes. Returns 1 if successful, else 0. 238 """ 239 output = self.loggedCommandOutput('gpt-query') 240 if not output: 241 self.setResult(0, 'gpt-query failed') 242 return 0 243 pat = '^\s*(' + string.join(prefixes, '|') + ')' 244 lastDefined = None 245 for pkg in output.split('\n'): 246 if not re.search(pat, pkg): 247 continue 248 (id, version) = re.search(r'^\s*([^-]+).*version:\s+(.*)$', pkg) 249 if not version: 250 continue 251 self.setSubpackageVersion(id, version) 252 lastDefined = id 253 if lastDefined == None: 254 self.setResult(0, 'package not installed (no GPT packages located)') 255 else: 256 self.setResult(1) 257 return self.getCompleted()
258
259 - def setVersionByRpmQuery(self, pattern):
260 """Set subpackage version information by querying GPT for packages that 261 contain the regular expression pattern. Returns 1 if successful, else 0. 262 """ 263 rpmCommand = \ 264 "(rpm -qa --qf='%{NAME} version:%{VERSION}\\n' | " + \ 265 "grep '^[^ ]*" + pattern + "')" 266 rpms = self.loggedCommandOutput(rpmCommand).split('\n'); 267 rpms.pop() # trim trailing empty element 268 if len(rpms) == 0: 269 self.setResult(0, 'no rpm packages found for ' + pattern) 270 return 0 271 for rpm in rpms: 272 (subpackage, version) = rpm.split(' version:') 273 self.setSubpackageVersion(subpackage, version) 274 self.setResult(1) 275 return 1;
276