66 # raptor_data module classes |
71 # raptor_data module classes |
67 |
72 |
68 class Model(object): |
73 class Model(object): |
69 "Base class for data-model objects" |
74 "Base class for data-model objects" |
70 |
75 |
|
76 __slots__ = ('host', 'source', 'cacheID') |
|
77 |
71 def __init__(self): |
78 def __init__(self): |
72 self.owner = None # Raptor object |
|
73 self.source = None # XML file |
79 self.source = None # XML file |
74 self.indent = " " # for DebugPrint |
|
75 self.host = None |
80 self.host = None |
76 self.cacheID = "" # default set of cached objects |
81 self.cacheID = "" # default set of cached objects |
77 |
82 # not using the cache parameter - there to make the |
78 |
83 # init for all Model objects "standard" |
79 def SetOwner(self, aRaptor): |
|
80 self.owner = aRaptor |
|
81 |
84 |
82 |
85 |
83 def SetSourceFile(self, filename): |
86 def SetSourceFile(self, filename): |
84 self.source = filename |
87 self.source = filename |
85 |
88 |
152 def __init__(self): |
150 def __init__(self): |
153 Model.__init__(self) # base class constructor |
151 Model.__init__(self) # base class constructor |
154 self.variants = [] |
152 self.variants = [] |
155 |
153 |
156 |
154 |
157 def SetOwner(self, aRaptor): |
155 def __str__(self): |
158 Model.SetOwner(self, aRaptor) |
156 return "\n".join([str(v) for v in self.variants]) |
159 for v in self.variants: |
|
160 v.SetOwner(aRaptor) |
|
161 |
|
162 |
|
163 def DebugPrint(self, prefix = ""): |
|
164 for v in self.variants: |
|
165 v.DebugPrint(prefix) |
|
166 |
157 |
167 |
158 |
168 def AddVariant(self, variant): |
159 def AddVariant(self, variant): |
169 if type(variant) is types.StringTypes: |
160 if type(variant) is types.StringTypes: |
170 variant = VariantRef(variant) |
161 variant = VariantRef(ref = variant) |
171 |
162 |
172 |
163 |
173 # Only add the variant if it's not in the list |
164 # Only add the variant if it's not in the list |
174 # already |
165 # already |
175 if not variant in self.variants: |
166 if not variant in self.variants: |
176 self.variants.append(variant) |
167 self.variants.append(variant) |
177 |
168 |
178 def GetVariants(self): |
169 def GetVariants(self, cache): |
179 # resolve any VariantRef objects into Variant objects |
170 # resolve any VariantRef objects into Variant objects |
|
171 missing_variants = [] |
180 for i,var in enumerate(self.variants): |
172 for i,var in enumerate(self.variants): |
181 if isinstance(var, Reference): |
173 if isinstance(var, Reference): |
182 try: |
174 try: |
183 self.variants[i] = var.Resolve() |
175 self.variants[i] = var.Resolve(cache=cache) |
184 |
176 |
185 except BadReferenceError: |
177 except BadReferenceError: |
186 self.owner.Error("Missing variant '%s'", var.ref) |
178 missing_variants.append(var.ref) |
|
179 |
|
180 if len(missing_variants) > 0: |
|
181 raise MissingVariantException("Missing variants '%s'", " ".join(missing_variants)) |
187 |
182 |
188 return self.variants |
183 return self.variants |
189 |
184 |
190 |
185 |
191 class Interface(Model): |
186 class Interface(Model): |
197 self.abstract = False |
192 self.abstract = False |
198 self.extends = None |
193 self.extends = None |
199 self.params = [] |
194 self.params = [] |
200 self.paramgroups = [] |
195 self.paramgroups = [] |
201 |
196 |
202 def DebugPrint(self, prefix = ""): |
197 def __str__(self): |
203 self.owner.Debug("%s<interface name='%s'>", prefix, self.name) |
198 return "<interface name='%s'>" % self.name + "</interface>" |
204 self.owner.Debug("%s...", prefix) |
199 |
205 self.owner.Debug("%s</interface>", prefix) |
200 def FindParent(self, cache): |
206 |
|
207 def FindParent(self): |
|
208 try: |
201 try: |
209 return self.owner.cache.FindNamedInterface(self.extends, self.cacheID) |
202 return cache.FindNamedInterface(self.extends, self.cacheID) |
210 except KeyError: |
203 except KeyError: |
211 raise BadReferenceError("Cannot extend interface because it cannot be found: "+str(self.extends)) |
204 raise BadReferenceError("Cannot extend interface because it cannot be found: "+str(self.extends)) |
212 |
205 |
213 def GetParams(self): |
206 def GetParams(self, cache): |
214 if self.extends != None: |
207 if self.extends != None: |
215 parent = self.FindParent() |
208 parent = self.FindParent(cache) |
216 |
209 |
217 # what parameter names do we have already? |
210 # what parameter names do we have already? |
218 names = set([x.name for x in self.params]) |
211 names = set([x.name for x in self.params]) |
219 |
212 |
220 # pick up ones we don't have that are in our parent |
213 # pick up ones we don't have that are in our parent |
221 pp = [] |
214 pp = [] |
222 for p in parent.GetParams(): |
215 for p in parent.GetParams(cache): |
223 if not p.name in names: |
216 if not p.name in names: |
224 pp.append(p) |
217 pp.append(p) |
225 |
218 |
226 # list parent parameters first then ours |
219 # list parent parameters first then ours |
227 pp.extend(self.params) |
220 pp.extend(self.params) |
228 return pp |
221 return pp |
229 |
222 |
230 return self.params |
223 return self.params |
231 |
224 |
232 def GetParamGroups(self): |
225 def GetParamGroups(self, cache): |
233 if self.extends != None: |
226 if self.extends != None: |
234 parent = self.FindParent() |
227 parent = self.FindParent(cache) |
235 |
228 |
236 # what parameter names do we have already? |
229 # what parameter names do we have already? |
237 patterns = set([x.pattern for x in self.paramgroups]) |
230 patterns = set([x.pattern for x in self.paramgroups]) |
238 |
231 |
239 # pick up ones we don't have that are in our parent |
232 # pick up ones we don't have that are in our parent |
240 for g in parent.GetParamGroups(): |
233 for g in parent.GetParamGroups(cache): |
241 if not g.pattern in patterns: |
234 if not g.pattern in patterns: |
242 self.paramgroups.append(g) |
235 self.paramgroups.append(g) |
243 |
236 |
244 return self.paramgroups |
237 return self.paramgroups |
245 |
238 |
246 |
239 |
247 def GetFLMIncludePath(self): |
240 def GetFLMIncludePath(self, cache): |
248 "absolute path to the FLM" |
241 "absolute path to the FLM" |
249 |
242 |
250 if self.flm == None: |
243 if self.flm == None: |
251 if self.extends != None: |
244 if self.extends != None: |
252 parent = self.FindParent() |
245 parent = self.FindParent(cache) |
253 |
246 |
254 return parent.GetFLMIncludePath() |
247 return parent.GetFLMIncludePath(cache) |
255 else: |
248 else: |
256 raise InvalidPropertyError() |
249 raise InvalidPropertyError() |
257 |
250 |
258 if not os.path.isabs(self.flm): |
251 if not os.path.isabs(self.flm): |
259 self.flm = os.path.join(os.path.dirname(self.source), self.flm) |
252 self.flm = os.path.join(os.path.dirname(self.source), self.flm) |
314 self.interface = None |
307 self.interface = None |
315 self.childSpecs = [] |
308 self.childSpecs = [] |
316 self.parentSpec = None |
309 self.parentSpec = None |
317 |
310 |
318 |
311 |
319 def DebugPrint(self, prefix = ""): |
312 def __str__(self): |
320 self.owner.Debug("%s<spec name='%s'>", prefix, self.name) |
313 s = "<spec name='%s'>" % str(self.name) |
321 if self.interface: |
314 s += VariantContainer.__str__(self) |
322 self.interface.DebugPrint(prefix + self.indent) |
|
323 VariantContainer.DebugPrint(self, prefix + self.indent) |
|
324 for c in self.childSpecs: |
315 for c in self.childSpecs: |
325 c.DebugPrint(prefix + self.indent) |
316 s += str(c) + '\n' |
326 self.owner.Debug("%s</spec>", prefix) |
317 s += "</spec>" |
327 |
318 return s |
328 |
|
329 def SetOwner(self, aRaptor): |
|
330 VariantContainer.SetOwner(self, aRaptor) |
|
331 |
|
332 if self.interface != None: |
|
333 self.interface.SetOwner(aRaptor) |
|
334 |
|
335 for s in self.childSpecs: |
|
336 s.SetOwner(aRaptor) |
|
337 |
319 |
338 |
320 |
339 def SetProperty(self, name, value): |
321 def SetProperty(self, name, value): |
340 if name == "name": |
322 if name == "name": |
341 self.name = value |
323 self.name = value |
342 else: |
324 else: |
343 raise InvalidPropertyError() |
325 raise InvalidPropertyError() |
344 |
326 |
345 |
327 |
346 def Configure(self, config): |
328 def Configure(self, config, cache): |
347 # configure all the children (some may be Filters or parents of) |
329 # configure all the children (some may be Filters or parents of) |
348 for spec in self.GetChildSpecs(): |
330 for spec in self.GetChildSpecs(): |
349 spec.Configure(config) |
331 spec.Configure(config, cache = cache) |
350 |
332 |
351 |
333 |
352 def HasInterface(self): |
334 def HasInterface(self): |
353 return self.interface != None |
335 return self.interface != None |
354 |
336 |
356 def SetInterface(self, interface): |
338 def SetInterface(self, interface): |
357 if isinstance(interface, Interface) \ |
339 if isinstance(interface, Interface) \ |
358 or isinstance(interface, InterfaceRef): |
340 or isinstance(interface, InterfaceRef): |
359 self.interface = interface |
341 self.interface = interface |
360 else: |
342 else: |
361 self.interface = InterfaceRef(interface) |
343 self.interface = InterfaceRef(ref = interface) |
362 |
344 |
363 |
345 |
364 def GetInterface(self): |
346 def GetInterface(self, cache): |
365 """return the Interface (fetching from the cache if it was a ref) |
347 """return the Interface (fetching from the cache if it was a ref) |
366 may return None""" |
348 may return None""" |
367 |
349 |
368 if self.interface == None \ |
350 if self.interface == None \ |
369 or isinstance(self.interface, Interface): |
351 or isinstance(self.interface, Interface): |
370 return self.interface |
352 return self.interface |
371 |
353 |
372 if isinstance(self.interface, InterfaceRef): |
354 if isinstance(self.interface, InterfaceRef): |
373 try: |
355 try: |
374 self.interface = self.interface.Resolve() |
356 self.interface = self.interface.Resolve(cache=cache) |
375 return self.interface |
357 return self.interface |
376 |
358 |
377 except BadReferenceError: |
359 except BadReferenceError: |
378 self.owner.Error("Missing interface %s", self.interface.ref) |
360 raise MissingInterfaceError("Missing interface %s" % self.interface.ref) |
379 return None |
|
380 |
|
381 |
361 |
382 def AddChild(self, child): |
362 def AddChild(self, child): |
383 if isinstance(child, Specification): |
363 if isinstance(child, Specification): |
384 self.AddChildSpecification(child) |
364 self.AddChildSpecification(child) |
385 elif isinstance(child, Interface) \ |
365 elif isinstance(child, Interface) \ |
407 |
387 |
408 def Valid(self): |
388 def Valid(self): |
409 return True |
389 return True |
410 |
390 |
411 |
391 |
412 def GetAllVariantsRecursively(self): |
392 def GetAllVariantsRecursively(self, cache): |
413 """Returns all variants contained in this node and in its ancestors. |
393 """Returns all variants contained in this node and in its ancestors. |
414 |
394 |
415 The returned value is a list, the structure of which is [variants-in-parent, |
395 The returned value is a list, the structure of which is [variants-in-parent, |
416 variants-in-self]. |
396 variants-in-self]. |
417 |
397 |
418 Note that the function recurses through parent *Specifications*, not through |
398 Note that the function recurses through parent *Specifications*, not through |
419 the variants themselves. |
399 the variants themselves. |
420 """ |
400 """ |
421 if self.parentSpec: |
401 if self.parentSpec: |
422 variants = self.parentSpec.GetAllVariantsRecursively() |
402 variants = self.parentSpec.GetAllVariantsRecursively(cache = cache) |
423 else: |
403 else: |
424 variants = [] |
404 variants = [] |
425 |
405 |
426 variants.extend( self.GetVariants() ) |
406 variants.extend( self.GetVariants(cache = cache) ) |
427 |
407 |
428 return variants |
408 return variants |
429 |
409 |
430 |
410 |
431 class Filter(Specification): |
411 class Filter(Specification): |
436 when the Configure method is called after setting up a Condition. |
416 when the Configure method is called after setting up a Condition. |
437 |
417 |
438 If several Conditions are set, the test is an OR of all of them.""" |
418 If several Conditions are set, the test is an OR of all of them.""" |
439 |
419 |
440 def __init__(self, name = ""): |
420 def __init__(self, name = ""): |
441 Specification.__init__(self, name) # base class constructor |
421 Specification.__init__(self, name = name) # base class constructor |
442 self.Else = Specification(name) # same for Else part |
422 self.Else = Specification(name = name) # same for Else part |
443 self.isTrue = True |
423 self.isTrue = True |
444 self.configNames = set() # |
424 self.configNames = set() # |
445 self.variableNames = set() # TO DO: Condition class |
425 self.variableNames = set() # TO DO: Condition class |
446 self.variableValues = {} # |
426 self.variableValues = {} # |
447 |
427 |
448 def DebugPrint(self, prefix = ""): |
428 def __str__(self, prefix = ""): |
449 self.owner.Debug("%s<filter name='%s'>", prefix, self.name) |
429 s = "<filter name='%s'>\n"% self.name |
450 self.owner.Debug("%s <if config='%s'>", prefix, " | ".join(self.configNames)) |
430 s += "<if config='%s'>\n" % " | ".join(self.configNames) |
451 Specification.DebugPrint(self, prefix + self.indent) |
431 s += Specification.__str__(self) |
452 self.owner.Debug("%s </if>", prefix) |
432 s += "</if>\n <else>\n" |
453 self.owner.Debug("%s <else>", prefix) |
433 s += str(self.Else) |
454 self.Else.DebugPrint(prefix + self.indent) |
434 s += " </else>\n</filter>\n" |
455 self.owner.Debug("%s </else>", prefix) |
435 return s |
456 self.owner.Debug("%s</filter>", prefix) |
|
457 |
436 |
458 |
437 |
459 def SetConfigCondition(self, configName): |
438 def SetConfigCondition(self, configName): |
460 self.configNames = set([configName]) |
439 self.configNames = set([configName]) |
461 |
440 |
476 self.variableValues[variableName] = set(variableValues) |
455 self.variableValues[variableName] = set(variableValues) |
477 else: |
456 else: |
478 self.variableValues[variableName] = set([variableValues]) |
457 self.variableValues[variableName] = set([variableValues]) |
479 |
458 |
480 |
459 |
481 def Configure(self, buildUnit): |
460 def Configure(self, buildUnit, cache): |
482 self.isTrue = False |
461 self.isTrue = False |
483 |
462 |
484 if buildUnit.name in self.configNames: |
463 if buildUnit.name in self.configNames: |
485 self.isTrue = True |
464 self.isTrue = True |
486 elif self.variableNames: |
465 elif self.variableNames: |
487 evaluator = self.owner.GetEvaluator(self.parentSpec, buildUnit) |
466 |
|
467 evaluator = Evaluator(self.parentSpec, buildUnit, cache=cache) |
488 |
468 |
489 for variableName in self.variableNames: |
469 for variableName in self.variableNames: |
490 variableValue = evaluator.Get(variableName) |
470 variableValue = evaluator.Get(variableName) |
491 |
471 |
492 if variableValue in self.variableValues[variableName]: |
472 if variableValue in self.variableValues[variableName]: |
493 self.isTrue = True |
473 self.isTrue = True |
494 break |
474 break |
495 |
475 |
496 # configure all the children too |
476 # configure all the children too |
497 for spec in self.GetChildSpecs(): |
477 for spec in self.GetChildSpecs(): |
498 spec.Configure(buildUnit) |
478 spec.Configure(buildUnit, cache=cache) |
499 |
|
500 |
|
501 def SetOwner(self, aRaptor): |
|
502 # base class method |
|
503 Specification.SetOwner(self, aRaptor) |
|
504 # same for Else part |
|
505 self.Else.SetOwner(aRaptor) |
|
506 |
479 |
507 |
480 |
508 def HasInterface(self): |
481 def HasInterface(self): |
509 if self.isTrue: |
482 if self.isTrue: |
510 return Specification.HasInterface(self) |
483 return Specification.HasInterface(self) |
511 else: |
484 else: |
512 return self.Else.HasInterface() |
485 return self.Else.HasInterface() |
513 |
486 |
514 |
487 |
515 def GetInterface(self): |
488 def GetInterface(self, cache): |
516 if self.isTrue: |
489 if self.isTrue: |
517 return Specification.GetInterface(self) |
490 return Specification.GetInterface(self, cache = cache) |
518 else: |
491 else: |
519 return self.Else.GetInterface() |
492 return self.Else.GetInterface(cache = cache) |
520 |
493 |
521 |
494 |
522 def GetVariants(self): |
495 def GetVariants(self, cache): |
523 if self.isTrue: |
496 if self.isTrue: |
524 return Specification.GetVariants(self) |
497 return Specification.GetVariants(self, cache = cache) |
525 else: |
498 else: |
526 return self.Else.GetVariants() |
499 return self.Else.GetVariants(cache = cache) |
527 |
500 |
528 |
501 |
529 def SetParentSpec(self, parent): |
502 def SetParentSpec(self, parent): |
530 # base class method |
503 # base class method |
531 Specification.SetParentSpec(self, parent) |
504 Specification.SetParentSpec(self, parent) |
589 return (self.pattern != None and self.patternre != None) |
562 return (self.pattern != None and self.patternre != None) |
590 |
563 |
591 |
564 |
592 class Operation(Model): |
565 class Operation(Model): |
593 "Base class for variant operations" |
566 "Base class for variant operations" |
|
567 __slots__ = 'type' |
594 def __init__(self): |
568 def __init__(self): |
595 Model.__init__(self) # base class constructor |
569 Model.__init__(self) # base class constructor |
596 self.type = None |
570 self.type = None |
597 |
571 |
598 |
|
599 def Apply(self, oldValue): |
572 def Apply(self, oldValue): |
600 pass |
573 pass |
601 |
574 |
602 |
575 |
603 class Append(Operation): |
576 class Append(Operation): |
604 __slots__ = ('name','value','separator','owner') |
577 __slots__ = ('name', 'value', 'separator') |
605 |
|
606 def __init__(self, name = None, value = None, separator = " "): |
578 def __init__(self, name = None, value = None, separator = " "): |
607 Operation.__init__(self) # base class constructor |
579 Operation.__init__(self) # base class constructor |
608 self.name = name |
580 self.name = name |
609 self.value = value |
581 self.value = value |
610 self.separator = separator |
582 self.separator = separator |
611 |
583 |
612 |
584 |
613 def DebugPrint(self, prefix = ""): |
585 def __str__(self): |
614 attributes = "name='" + self.name + "' value='" + self.value + "' separator='" + self.separator + "'" |
586 attributes = "name='" + self.name + "' value='" + self.value + "' separator='" + self.separator + "'" |
615 self.owner.Debug("%s<append %s/>", prefix, attributes) |
587 return "<append %s/>" % attributes |
616 |
588 |
617 |
589 |
618 def Apply(self, oldValue): |
590 def Apply(self, oldValue): |
619 if len(oldValue) > 0: |
591 if len(oldValue) > 0: |
620 if len(self.value) > 0: |
592 if len(self.value) > 0: |
639 def Valid(self): |
611 def Valid(self): |
640 return (self.name != None and self.value != None) |
612 return (self.name != None and self.value != None) |
641 |
613 |
642 |
614 |
643 class Prepend(Operation): |
615 class Prepend(Operation): |
|
616 __slots__ = ('name', 'value', 'separator') |
644 def __init__(self, name = None, value = None, separator = " "): |
617 def __init__(self, name = None, value = None, separator = " "): |
645 Operation.__init__(self) # base class constructor |
618 Operation.__init__(self) # base class constructor |
646 self.name = name |
619 self.name = name |
647 self.value = value |
620 self.value = value |
648 self.separator = separator |
621 self.separator = separator |
649 |
622 |
650 |
623 |
651 def DebugPrint(self, prefix = ""): |
624 def __str__(self, prefix = ""): |
652 attributes = "name='" + self.name + "' value='" + self.value + "' separator='" + self.separator + "'" |
625 attributes = "name='" + self.name + "' value='" + self.value + "' separator='" + self.separator + "'" |
653 self.owner.Debug("%s<prepend %s/>", prefix, attributes) |
626 return "<prepend %s/>" % prefix |
654 |
627 |
655 |
628 |
656 def Apply(self, oldValue): |
629 def Apply(self, oldValue): |
657 if len(oldValue) > 0: |
630 if len(oldValue) > 0: |
658 if len(self.value) > 0: |
631 if len(self.value) > 0: |
677 def Valid(self): |
650 def Valid(self): |
678 return (self.name != None and self.value != None) |
651 return (self.name != None and self.value != None) |
679 |
652 |
680 |
653 |
681 class Set(Operation): |
654 class Set(Operation): |
|
655 __slots__ = ('name', 'value', 'type', 'versionCommand', 'versionResult') |
682 """implementation of <set> operation""" |
656 """implementation of <set> operation""" |
683 __slots__ = ('name','value', 'type', 'versionCommand', 'versionResult', 'owner') |
|
684 |
657 |
685 def __init__(self, name = None, value = "", type = ""): |
658 def __init__(self, name = None, value = "", type = ""): |
686 Operation.__init__(self) # base class constructor |
659 Operation.__init__(self) # base class constructor |
687 self.name = name |
660 self.name = name |
688 self.value = value |
661 self.value = value |
689 self.type = type |
662 self.type = type |
690 self.versionCommand = "" |
663 self.versionCommand = "" |
691 self.versionResult = "" |
664 self.versionResult = "" |
692 |
665 |
693 |
666 |
694 def DebugPrint(self, prefix = ""): |
667 def __str__(self): |
695 attributes = "name='" + self.name + "' value='" + self.value + "' type='" + self.type + "'" |
668 attributes = "name='" + self.name + "' value='" + self.value + "' type='" + self.type + "'" |
696 if type == "tool": |
669 if type == "tool": |
697 attributes += " versionCommand='" + self.versionCommand + "' versionResult='" + self.versionResult |
670 attributes += " versionCommand='" + self.versionCommand + "' versionResult='" + self.versionResult |
698 |
671 |
699 self.owner.Debug("%s<set %s/>", prefix, attributes) |
672 return "<set %s/>" % attributes |
700 |
673 |
701 |
674 |
702 def Apply(self, oldValue): |
675 def Apply(self, oldValue): |
703 return self.value |
676 return self.value |
704 |
677 |
722 |
695 |
723 |
696 |
724 def Valid(self): |
697 def Valid(self): |
725 return (self.name != None and self.value != None) |
698 return (self.name != None and self.value != None) |
726 |
699 |
|
700 class BadToolValue(Exception): |
|
701 pass |
727 |
702 |
728 class Env(Set): |
703 class Env(Set): |
729 """implementation of <env> operator""" |
704 """implementation of <env> operator""" |
730 |
705 |
731 def __init__(self, name = None, default = None, type = ""): |
706 def __init__(self, name = None, default = None, type = ""): |
732 Set.__init__(self, name, "", type) # base class constructor |
707 Set.__init__(self, name, "", type) # base class constructor |
733 self.default = default |
708 self.default = default |
734 |
709 |
735 |
710 |
736 def DebugPrint(self, prefix = ""): |
711 def __str__(self): |
737 attributes = "name='" + self.name + "' type='" + self.type + "'" |
712 attributes = "name='" + self.name + "' type='" + self.type + "'" |
738 if default != None: |
713 if default != None: |
739 attributes += " default='" + self.default + "'" |
714 attributes += " default='" + self.default + "'" |
740 |
715 |
741 if type == "tool": |
716 if type == "tool": |
742 attributes += " versionCommand='" + self.versionCommand + "' versionResult='" + self.versionResult + "'" |
717 attributes += " versionCommand='" + self.versionCommand + "' versionResult='" + self.versionResult + "'" |
743 |
718 |
744 self.owner.Debug("%s<env %s/>", prefix, attributes) |
719 return "<env %s/>" % attributes |
745 |
720 |
746 |
721 |
747 def Apply(self, oldValue): |
722 def Apply(self, oldValue): |
748 try: |
723 try: |
749 value = os.environ[self.name] |
724 value = os.environ[self.name] |
753 if value and (self.type == "path" or self.type == "tool"): |
728 if value and (self.type == "path" or self.type == "tool"): |
754 try: |
729 try: |
755 path = generic_path.Path(value) |
730 path = generic_path.Path(value) |
756 value = str(path.Absolute()) |
731 value = str(path.Absolute()) |
757 except ValueError,e: |
732 except ValueError,e: |
758 self.owner.Error("the environment variable %s is incorrect: %s" % (self.name, str(e))) |
733 raise BadToolValue("the environment variable %s is incorrect: %s" % (self.name, str(e))) |
759 return "NO_VALUE_FOR_" + self.name |
|
760 except KeyError: |
734 except KeyError: |
761 if self.default != None: |
735 if self.default != None: |
762 value = self.default |
736 value = self.default |
763 else: |
737 else: |
764 self.owner.Error("%s is not set in the environment and has no default", self.name) |
738 raise BadToolValue("%s is not set in the environment and has no default" % self.name) |
765 return "NO_VALUE_FOR_" + self.name |
|
766 |
739 |
767 return value |
740 return value |
768 |
741 |
769 |
742 |
770 def SetProperty(self, name, value): |
743 def SetProperty(self, name, value): |
789 |
762 |
790 # Cache for the variant operations implied by this BuildUnit. |
763 # Cache for the variant operations implied by this BuildUnit. |
791 self.operations = [] |
764 self.operations = [] |
792 self.variantKey = "" |
765 self.variantKey = "" |
793 |
766 |
794 def GetOperations(self): |
767 def GetOperations(self, cache): |
795 """Return all operations related to this BuildUnit. |
768 """Return all operations related to this BuildUnit. |
796 |
769 |
797 The result is cached, and so will only be computed once per BuildUnit. |
770 The result is cached, and so will only be computed once per BuildUnit. |
798 """ |
771 """ |
799 key = '.'.join([x.name for x in self.variants]) |
772 key = '.'.join([x.name for x in self.variants]) |
800 if self.variantKey != key: |
773 if self.variantKey != key: |
801 self.variantKey = key |
774 self.variantKey = key |
802 for v in self.variants: |
775 for v in self.variants: |
803 self.operations.extend( v.GetAllOperationsRecursively() ) |
776 self.operations.extend( v.GetAllOperationsRecursively(cache=cache) ) |
804 |
777 |
805 return self.operations |
778 return self.operations |
806 |
779 |
807 class Config(object): |
780 class Config(object): |
808 """Abstract type representing an argument to the '-c' option. |
781 """Abstract type representing an argument to the '-c' option. |
818 self.modifiers.append(variant) |
791 self.modifiers.append(variant) |
819 |
792 |
820 def ClearModifiers(self): |
793 def ClearModifiers(self): |
821 self.modifiers = [] |
794 self.modifiers = [] |
822 |
795 |
823 def GenerateBuildUnits(self): |
796 def GenerateBuildUnits(self,cache): |
824 """Returns a list of BuildUnits. |
797 """Returns a list of BuildUnits. |
825 |
798 |
826 This function must be overridden by derived classes. |
799 This function must be overridden by derived classes. |
827 """ |
800 """ |
828 raise NotImplementedError() |
801 raise NotImplementedError() |
829 |
802 |
830 |
803 |
831 class Variant(Model, Config): |
804 class Variant(Model, Config): |
|
805 |
|
806 __slots__ = ('cache','name','host','extends','ops','variantRefs','allOperations') |
832 |
807 |
833 def __init__(self, name = ""): |
808 def __init__(self, name = ""): |
834 Model.__init__(self) |
809 Model.__init__(self) |
835 Config.__init__(self) |
810 Config.__init__(self) |
836 self.name = name |
811 self.name = name |
866 raise InvalidChildError() |
841 raise InvalidChildError() |
867 |
842 |
868 def Valid(self): |
843 def Valid(self): |
869 return self.name |
844 return self.name |
870 |
845 |
871 def SetOwner(self, aRaptor): |
|
872 |
|
873 Model.SetOwner(self, aRaptor) |
|
874 |
|
875 for r in self.variantRefs: |
|
876 r.SetOwner(aRaptor) |
|
877 |
|
878 for op in self.ops: |
|
879 op.SetOwner(aRaptor) |
|
880 |
|
881 def AddOperation(self, op): |
846 def AddOperation(self, op): |
882 self.ops.append(op) |
847 self.ops.append(op) |
883 |
848 |
884 def GetAllOperationsRecursively(self): |
849 def GetAllOperationsRecursively(self, cache): |
885 """Returns a list of all operations in this variant. |
850 """Returns a list of all operations in this variant. |
886 |
851 |
887 The list elements are themselves lists; the overall structure of the |
852 The list elements are themselves lists; the overall structure of the |
888 returned value is: |
853 returned value is: |
889 |
854 |
890 [ [ops-from-parent],[ops-from-varRefs], [ops-in-self] ] |
855 [ [ops-from-parent],[ops-from-varRefs], [ops-in-self] ] |
891 """ |
856 """ |
892 |
857 |
893 if not self.allOperations: |
858 if not self.allOperations: |
894 if self.extends: |
859 if self.extends: |
895 parent = self.owner.cache.FindNamedVariant(self.extends) |
860 parent = cache.FindNamedVariant(self.extends) |
896 self.allOperations.extend( parent.GetAllOperationsRecursively() ) |
861 self.allOperations.extend( parent.GetAllOperationsRecursively(cache = cache) ) |
897 for r in self.variantRefs: |
862 for r in self.variantRefs: |
898 for v in [ r.Resolve() ] + r.GetModifiers(): |
863 for v in [ r.Resolve(cache = cache) ] + r.GetModifiers(cache = cache): |
899 self.allOperations.extend( v.GetAllOperationsRecursively() ) |
864 self.allOperations.extend( v.GetAllOperationsRecursively(cache = cache) ) |
900 self.allOperations.append(self.ops) |
865 self.allOperations.append(self.ops) |
901 |
866 |
902 return self.allOperations |
867 return self.allOperations |
903 |
868 |
904 def GenerateBuildUnits(self): |
869 def GenerateBuildUnits(self,cache): |
905 |
870 |
906 name = self.name |
871 name = self.name |
907 vars = [self] |
872 vars = [self] |
908 |
873 |
909 for m in self.modifiers: |
874 for m in self.modifiers: |
910 name = name + "." + m.name |
875 name = name + "." + m.name |
911 vars.append(m) |
876 vars.append(m) |
912 |
877 return [ BuildUnit(name=name, variants=vars) ] |
913 return [ BuildUnit(name, vars) ] |
878 |
914 |
879 def __str__(self): |
915 def DebugPrint(self, prefix = ""): |
880 s = "<var name='%s' extends='%s'>\n" % (self.name, self.extends) |
916 |
|
917 self.owner.Debug("%s<var name='%s' extends='%s'>", prefix, self.name, self.extends) |
|
918 for op in self.ops: |
881 for op in self.ops: |
919 op.DebugPrint(prefix + self.indent) |
882 s += str(op) + '\n' |
920 |
883 s += "</var>" |
921 self.owner.Debug("%s</var>", prefix) |
884 return s |
922 |
885 |
923 |
886 import traceback |
924 class VariantRef(Reference): |
887 class VariantRef(Reference): |
925 |
888 |
926 def __init__(self, ref=None): |
889 def __init__(self, ref=None): |
927 Reference.__init__(self, ref) |
890 Reference.__init__(self, ref = ref) |
928 |
891 |
929 def DebugPrint(self, prefix = ""): |
892 def __str__(self): |
930 self.owner.Debug("%s<varRef ref='%s'/>", prefix, self.ref) |
893 return "<varRef ref='%s'/>" % self.ref |
931 |
894 |
932 def Resolve(self): |
895 def Resolve(self, cache): |
933 try: |
896 try: |
934 return self.owner.cache.FindNamedVariant(self.ref) |
897 return cache.FindNamedVariant(self.ref) |
935 except KeyError: |
898 except KeyError, e: |
936 raise BadReferenceError(self.ref) |
899 raise BadReferenceError(self.ref) |
937 |
900 |
|
901 class MissingVariantException(Exception): |
|
902 pass |
938 |
903 |
939 class Alias(Model, Config): |
904 class Alias(Model, Config): |
940 |
905 |
941 def __init__(self, name=""): |
906 def __init__(self, name=""): |
942 Model.__init__(self) |
907 Model.__init__(self) |
944 self.name = name |
909 self.name = name |
945 self.meaning = "" |
910 self.meaning = "" |
946 self.varRefs = [] |
911 self.varRefs = [] |
947 self.variants = [] |
912 self.variants = [] |
948 |
913 |
949 def DebugPrint(self, prefix = ""): |
914 def __str__(self): |
950 self.owner.Debug("%s<alias name='%s' meaning='%s'/>", prefix, self.name, self.meaning) |
915 return "<alias name='%s' meaning='%s'/>" % (self.name, self.meaning) |
951 |
916 |
952 def SetProperty(self, key, val): |
917 def SetProperty(self, key, val): |
953 if key == "name": |
918 if key == "name": |
954 self.name = val |
919 self.name = val |
955 elif key == "meaning": |
920 elif key == "meaning": |
956 self.meaning = val |
921 self.meaning = val |
957 |
922 |
958 for u in val.split("."): |
923 for u in val.split("."): |
959 self.varRefs.append( VariantRef(u) ) |
924 self.varRefs.append( VariantRef(ref = u) ) |
960 else: |
925 else: |
961 raise InvalidPropertyError() |
926 raise InvalidPropertyError() |
962 |
|
963 def SetOwner(self, raptor): |
|
964 Model.SetOwner(self, raptor) |
|
965 for r in self.varRefs: |
|
966 r.SetOwner(raptor) |
|
967 |
927 |
968 def Valid(self): |
928 def Valid(self): |
969 return self.name and self.meaning |
929 return self.name and self.meaning |
970 |
930 |
971 def GenerateBuildUnits(self): |
931 def GenerateBuildUnits(self, cache): |
972 if not self.variants: |
932 if not self.variants: |
|
933 missing_variants = [] |
973 for r in self.varRefs: |
934 for r in self.varRefs: |
974 try: |
935 try: |
975 self.variants.append( r.Resolve() ) |
936 self.variants.append( r.Resolve(cache=cache) ) |
976 except BadReferenceError: |
937 except BadReferenceError: |
977 self.owner.Error("Missing variant '%s'", r.ref) |
938 missing_variants.append(r.ref) |
|
939 |
|
940 if len(missing_variants) > 0: |
|
941 raise MissingVariantException("Missing variants '%s'", " ".join(missing_variants)) |
978 |
942 |
979 name = self.name |
943 name = self.name |
980 |
944 |
981 for v in self.modifiers: |
945 for v in self.modifiers: |
982 name = name + "." + v.name |
946 name = name + "." + v.name |
983 |
947 |
984 return [ BuildUnit(name, self.variants + self.modifiers) ] |
948 return [ BuildUnit(name=name, variants=self.variants + self.modifiers) ] |
985 |
949 |
986 |
950 |
987 class AliasRef(Reference): |
951 class AliasRef(Reference): |
988 |
952 |
989 def __init__(self, ref=None): |
953 def __init__(self, ref=None): |
990 Reference.__init__(self, ref) |
954 Reference.__init__(self, ref) |
991 |
955 |
992 def DebugPrint(self, prefix = ""): |
956 def __str__(self): |
993 self.owner.Debug("%s<aliasRef ref='%s'/>", prefix, self.ref) |
957 return "<aliasRef ref='%s'/>" % self.ref |
994 |
958 |
995 def Resolve(self): |
959 def Resolve(self, cache): |
996 try: |
960 try: |
997 return self.owner.cache.FindNamedAlias(self.ref) |
961 return cache.FindNamedAlias(self.ref) |
998 except KeyError: |
962 except KeyError: |
999 raise BadReferenceError(self.ref) |
963 raise BadReferenceError(self.ref) |
1000 |
964 |
1001 |
965 |
1002 class Group(Model, Config): |
966 class Group(Model, Config): |
1016 if isinstance( child, (VariantRef,AliasRef,GroupRef) ): |
980 if isinstance( child, (VariantRef,AliasRef,GroupRef) ): |
1017 self.childRefs.append(child) |
981 self.childRefs.append(child) |
1018 else: |
982 else: |
1019 raise InvalidChildError() |
983 raise InvalidChildError() |
1020 |
984 |
1021 def SetOwner(self, raptor): |
|
1022 Model.SetOwner(self, raptor) |
|
1023 for r in self.childRefs: |
|
1024 r.SetOwner(raptor) |
|
1025 |
|
1026 def Valid(self): |
985 def Valid(self): |
1027 return self.name and self.childRefs |
986 return self.name and self.childRefs |
1028 |
987 |
1029 def DebugPrint(self, prefix = ""): |
988 def __str__(self): |
1030 |
989 s = "<group name='%s'>" % self.name |
1031 self.owner.Debug("<group name='%s'>", prefix, self.name) |
|
1032 |
|
1033 for r in self.childRefs: |
990 for r in self.childRefs: |
1034 r.DebugPrint(prefix + self.indent) |
991 s += str(r) |
1035 |
992 s += "</group>" |
1036 self.owner.Debug("%s</group>", prefix) |
993 return s |
1037 |
994 |
1038 def GenerateBuildUnits(self): |
995 def GenerateBuildUnits(self, cache): |
1039 |
|
1040 units = [] |
996 units = [] |
1041 |
997 |
|
998 missing_variants = [] |
1042 for r in self.childRefs: |
999 for r in self.childRefs: |
1043 refMods = r.GetModifiers() |
1000 refMods = r.GetModifiers(cache) |
1044 |
1001 |
1045 try: |
1002 try: |
1046 obj = r.Resolve() |
1003 obj = r.Resolve(cache=cache) |
1047 except BadReferenceError: |
1004 except BadReferenceError: |
1048 self.owner.Error("Missing variant '%s'", r.ref) |
1005 missing_variants.append(r.ref) |
1049 else: |
1006 else: |
1050 obj.ClearModifiers() |
1007 obj.ClearModifiers() |
1051 |
1008 |
1052 for m in refMods + self.modifiers: |
1009 for m in refMods + self.modifiers: |
1053 obj.AddModifier(m) |
1010 obj.AddModifier(m) |
1054 |
1011 |
1055 units.extend( obj.GenerateBuildUnits() ) |
1012 units.extend( obj.GenerateBuildUnits(cache) ) |
|
1013 |
|
1014 if len(missing_variants) > 0: |
|
1015 raise MissingVariantException("Missing variants '%s'", " ".join(missing_variants)) |
1056 |
1016 |
1057 return units |
1017 return units |
1058 |
1018 |
1059 |
1019 |
1060 class GroupRef(Reference): |
1020 class GroupRef(Reference): |
1061 |
1021 |
1062 def __init__(self, ref=None): |
1022 def __init__(self, ref=None): |
1063 Reference.__init__(self, ref) |
1023 Reference.__init__(self, ref) |
1064 |
1024 |
1065 def DebugPrint(self, prefix = ""): |
1025 def __str__(self): |
1066 mod = ".".join(self.modifiers) |
1026 return "<%s /><groupRef ref='%s' mod='%s'/>" % (prefix, self.ref, ".".join(self.modifiers)) |
1067 self.owner.Debug("%s<groupRef ref='%s' mod='%s'/>", prefix, self.ref, mod) |
1027 |
1068 |
1028 def Resolve(self, cache): |
1069 def Resolve(self): |
|
1070 try: |
1029 try: |
1071 return self.owner.cache.FindNamedGroup(self.ref) |
1030 return cache.FindNamedGroup(self.ref) |
1072 except KeyError: |
1031 except KeyError: |
1073 raise BadReferenceError(self.ref) |
1032 raise BadReferenceError(self.ref) |
1074 |
1033 |
|
1034 class ToolErrorException(Exception): |
|
1035 def __init__(self, s): |
|
1036 Exception.__init__(self,s) |
|
1037 |
1075 class Tool(object): |
1038 class Tool(object): |
1076 """Represents a tool that might be used by raptor e.g. a compiler""" |
1039 """Represents a tool that might be used by raptor e.g. a compiler""" |
|
1040 |
|
1041 # It's difficult and expensive to give each tool a log reference but a class one |
|
1042 # will facilitate debugging when that is needed without being a design flaw the |
|
1043 # rest of the time. |
|
1044 log = raptor_utilities.nulllog |
1077 |
1045 |
1078 # For use in dealing with tools that return non-ascii version strings. |
1046 # For use in dealing with tools that return non-ascii version strings. |
1079 nonascii = "" |
1047 nonascii = "" |
1080 identity_chartable = chr(0) |
1048 identity_chartable = chr(0) |
1081 for c in xrange(1,128): |
1049 for c in xrange(1,128): |
1082 identity_chartable += chr(c) |
1050 identity_chartable += chr(c) |
1083 for c in xrange(128,256): |
1051 for c in xrange(128,256): |
1084 nonascii += chr(c) |
1052 nonascii += chr(c) |
1085 identity_chartable += " " |
1053 identity_chartable += " " |
1086 |
1054 |
1087 def __init__(self, name, command, versioncommand, versionresult, id="", log = raptor_utilities.nulllog): |
1055 def __init__(self, name, command, versioncommand, versionresult, id=""): |
1088 self.name = name |
1056 self.name = name |
1089 self.command = command |
1057 self.command = command |
1090 self.versioncommand = versioncommand |
1058 self.versioncommand = versioncommand |
1091 self.versionresult = versionresult |
1059 self.versionresult = versionresult |
1092 self.id = id # what config this is from - used in debug messages |
1060 self.id = id # what config this is from - used in debug messages |
1115 # executable file (e.g. "armcc" rather than "python myscript.py") then get it's date. |
1082 # executable file (e.g. "armcc" rather than "python myscript.py") then get it's date. |
1116 # We can use the date later to see if our cache is valid. |
1083 # We can use the date later to see if our cache is valid. |
1117 # If it really is not a simple command then we won't be able to get a date and |
1084 # If it really is not a simple command then we won't be able to get a date and |
1118 # we won't be able to tell if it is altered or updated - too bad! |
1085 # we won't be able to tell if it is altered or updated - too bad! |
1119 testfile = generic_path.Where(self.command) |
1086 testfile = generic_path.Where(self.command) |
1120 self.log.Debug("toolcheck: tool '%s' was found on the path at '%s' ", self.command, testfile) |
1087 #self.log.Debug("toolcheck: tool '%s' was found on the path at '%s' ", self.command, testfile) |
1121 if testfile is None: |
1088 if testfile is None: |
1122 raise Exception("Can't be found in path") |
1089 raise Exception("Can't be found in path") |
1123 |
1090 |
1124 if not os.path.isfile(testfile): |
1091 if not os.path.isfile(testfile): |
1125 raise Exception("tool %s appears to not be a file %s", self.command, testfile) |
1092 raise Exception("tool %s appears to not be a file %s", self.command, testfile) |
1126 |
1093 |
1127 testfile_stat = os.stat(testfile) |
1094 testfile_stat = os.stat(testfile) |
1128 self.date = testfile_stat.st_mtime |
1095 self.date = testfile_stat.st_mtime |
1129 except Exception,e: |
1096 except Exception,e: |
1130 self.log.Debug("toolcheck: '%s=%s' cannot be dated - this is ok, but the toolcheck won't be able to tell when a new of the tool is installed. (%s)", self.name, self.command, str(e)) |
1097 # We really don't mind if the tool could not be dated - for any reason |
|
1098 Tool.log.Debug("toolcheck: '%s=%s' cannot be dated - this is ok, but the toolcheck won't be able to tell when a new version of the tool is installed. (%s)", self.name, self.command, str(e)) |
|
1099 pass |
1131 |
1100 |
1132 |
1101 |
1133 def check(self, shell, evaluator): |
1102 def check(self, shell, evaluator, log = raptor_utilities.nulllog): |
1134 |
1103 |
1135 self.vre = re.compile(self.versionresult) |
1104 self.vre = re.compile(self.versionresult) |
1136 |
1105 |
1137 try: |
1106 try: |
1138 self.log.Debug("Pre toolcheck: '%s' for version '%s'", self.name, self.versionresult) |
1107 self.log.Debug("Pre toolcheck: '%s' for version '%s'", self.name, self.versionresult) |
1139 p = subprocess.Popen(args=[shell, "-c", self.versioncommand], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
1108 p = subprocess.Popen(args=[shell, "-c", self.versioncommand], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
|
1109 log.Debug("Checking tool '%s' for version '%s'", self.name, self.versionresult) |
1140 versionoutput,err = p.communicate() |
1110 versionoutput,err = p.communicate() |
1141 self.log.Debug("Checking tool '%s' for version '%s'", self.name, self.versionresult) |
|
1142 except Exception,e: |
1111 except Exception,e: |
1143 versionoutput=None |
1112 versionoutput=None |
1144 |
1113 |
1145 # Some tools return version strings with unicode characters! |
1114 # Some tools return version strings with unicode characters! |
1146 # There is no good response other than a lot of decoding and encoding. |
1115 # There is no good response other than a lot of decoding and encoding. |
1147 # Simpler to ignore it: |
1116 # Simpler to ignore it: |
1148 versionoutput_a = versionoutput.translate(Tool.identity_chartable,"") |
1117 versionoutput_a = versionoutput.translate(Tool.identity_chartable,"") |
1149 |
1118 |
1150 if versionoutput_a and self.vre.search(versionoutput_a) != None: |
1119 if versionoutput_a and self.vre.search(versionoutput_a) != None: |
1151 self.log.Debug("tool '%s' returned an acceptable version '%s' at %s", self.name, versionoutput_a, str(self.date)) |
1120 log.Debug("tool '%s' returned an acceptable version '%s'", self.name, versionoutput_a) |
1152 self.valid = True |
1121 self.valid = True |
1153 else: |
1122 else: |
1154 self.log.Error("tool '%s' from config '%s' did not return version '%s' as required.\nCommand '%s' returned:\n%s\nCheck your environment and configuration.\n", self.name, self.id, self.versionresult, self.versioncommand, versionoutput_a) |
|
1155 self.valid = False |
1123 self.valid = False |
1156 return self.valid |
1124 raise ToolErrorException("tool '%s' from config '%s' did not return version '%s' as required.\nCommand '%s' returned:\n%s\nCheck your environment and configuration.\n" % (self.name, self.id, self.versionresult, self.versioncommand, versionoutput_a)) |
1157 |
1125 |
1158 def envhash(irrelevant_vars): |
1126 def envhash(irrelevant_vars): |
1159 """Determine something unique about this environment to identify it. |
1127 """Determine something unique about this environment to identify it. |
1160 must ignore variables that change without mattering to the caller |
1128 must ignore variables that change without mattering to the caller |
1161 e.g. perhaps PATH matters but PWD and PPID don't""" |
1129 e.g. perhaps PATH matters but PWD and PPID don't""" |
1173 toolset.check() is called for each config but the cache is kept across calls to |
1141 toolset.check() is called for each config but the cache is kept across calls to |
1174 catch the use of one tool in many configs. |
1142 catch the use of one tool in many configs. |
1175 write() is used to flush the cache to disc. |
1143 write() is used to flush the cache to disc. |
1176 """ |
1144 """ |
1177 # The raptor shell - this is not mutable. |
1145 # The raptor shell - this is not mutable. |
1178 hostbinaries = os.path.join(os.environ['SBS_HOME'], |
1146 if 'SBS_SHELL' in os.environ: |
1179 os.environ['HOSTPLATFORM_DIR']) |
1147 shell = os.environ['SBS_SHELL'] |
|
1148 else: |
|
1149 hostbinaries = os.path.join(os.environ['SBS_HOME'], |
|
1150 os.environ['HOSTPLATFORM_DIR']) |
1180 |
1151 |
1181 if HostPlatform.IsHost('lin*'): |
1152 if HostPlatform.IsHost('lin*'): |
1182 shell=os.path.join(hostbinaries, 'bin/bash') |
1153 shell=os.path.join(hostbinaries, 'bin/bash') |
1183 else: |
1154 else: |
1184 if 'SBS_CYGWIN' in os.environ: |
1155 if 'SBS_CYGWIN' in os.environ: |
1185 shell=os.path.join(os.environ['SBS_CYGWIN'], 'bin\\bash.exe') |
1156 shell=os.path.join(os.environ['SBS_CYGWIN'], 'bin\\bash.exe') |
1186 else: |
1157 else: |
1187 shell=os.path.join(hostbinaries, 'cygwin\\bin\\bash.exe') |
1158 shell=os.path.join(hostbinaries, 'cygwin\\bin\\bash.exe') |
1188 |
1159 |
1189 |
1160 |
1190 irrelevant_vars = ['PWD','OLDPWD','PID','PPID', 'SHLVL' ] |
1161 irrelevant_vars = ['PWD','OLDPWD','PID','PPID', 'SHLVL' ] |
1191 |
1162 |
1192 |
1163 |
1253 self.__toolcheckcache[toolhistory[0]] = ce |
1224 self.__toolcheckcache[toolhistory[0]] = ce |
1254 log.Info("Loaded toolcheck cache: %s\n", self.cachefilename) |
1225 log.Info("Loaded toolcheck cache: %s\n", self.cachefilename) |
1255 except Exception, e: |
1226 except Exception, e: |
1256 log.Info("Ignoring garbled toolcheck cache: %s (%s)\n", self.cachefilename, str(e)) |
1227 log.Info("Ignoring garbled toolcheck cache: %s (%s)\n", self.cachefilename, str(e)) |
1257 self.__toolcheckcache = {} |
1228 self.__toolcheckcache = {} |
1258 |
|
1259 |
1229 |
1260 else: |
1230 else: |
1261 log.Info("Toolcheck cache %s ignored - environment changed\n", self.cachefilename) |
1231 log.Info("Toolcheck cache %s ignored - environment changed\n", self.cachefilename) |
1262 else: |
1232 else: |
1263 log.Info("Toolcheck cache not loaded = marker missing: %s %s\n", self.cachefilename, ToolSet.filemarker) |
1233 log.Info("Toolcheck cache not loaded = marker missing: %s %s\n", self.cachefilename, ToolSet.filemarker) |
1354 self.log.Info("Created/Updated toolcheck cache: %s\n", self.cachefilename) |
1327 self.log.Info("Created/Updated toolcheck cache: %s\n", self.cachefilename) |
1355 except Exception, e: |
1328 except Exception, e: |
1356 self.log.Info("Could not write toolcheck cache: %s", str(e)) |
1329 self.log.Info("Could not write toolcheck cache: %s", str(e)) |
1357 return self.valid |
1330 return self.valid |
1358 |
1331 |
|
1332 class UninitialisedVariableException(Exception): |
|
1333 pass |
1359 |
1334 |
1360 class Evaluator(object): |
1335 class Evaluator(object): |
1361 """Determine the values of variables under different Configurations. |
1336 """Determine the values of variables under different Configurations. |
1362 Either of specification and buildUnit may be None.""" |
1337 Either of specification and buildUnit may be None.""" |
1363 |
1338 |
1364 |
1339 |
1365 refRegex = re.compile("\$\((.+?)\)") |
1340 refRegex = re.compile("\$\((.+?)\)") |
1366 |
1341 |
1367 def __init__(self, Raptor, specification, buildUnit, gathertools = False): |
1342 def __init__(self, specification, buildUnit, cache, gathertools = False): |
1368 self.raptor = Raptor |
|
1369 self.dict = {} |
1343 self.dict = {} |
1370 self.tools = [] |
1344 self.tools = [] |
1371 self.gathertools = gathertools |
1345 self.gathertools = gathertools |
|
1346 self.cache = cache |
1372 |
1347 |
1373 specName = "none" |
1348 specName = "none" |
1374 configName = "none" |
1349 configName = "none" |
1375 |
1350 |
1376 # A list of lists of operations. |
1351 # A list of lists of operations. |
1377 opsLists = [] |
1352 opsLists = [] |
1378 |
1353 |
1379 if buildUnit: |
1354 if buildUnit: |
1380 opsLists.extend( buildUnit.GetOperations() ) |
1355 ol = buildUnit.GetOperations(cache) |
|
1356 self.buildUnit = buildUnit |
|
1357 |
|
1358 opsLists.extend( ol ) |
1381 |
1359 |
1382 if specification: |
1360 if specification: |
1383 for v in specification.GetAllVariantsRecursively(): |
1361 for v in specification.GetAllVariantsRecursively(cache): |
1384 opsLists.extend( v.GetAllOperationsRecursively() ) |
1362 opsLists.extend( v.GetAllOperationsRecursively(cache) ) |
1385 |
1363 |
1386 tools = {} |
1364 tools = {} |
1387 |
1365 |
|
1366 unfound_values = [] |
1388 for opsList in opsLists: |
1367 for opsList in opsLists: |
1389 for op in opsList: |
1368 for op in opsList: |
1390 # applying an Operation to a non-existent variable |
1369 # applying an Operation to a non-existent variable |
1391 # is OK. We assume that it is just an empty string. |
1370 # is OK. We assume that it is just an empty string. |
1392 try: |
1371 try: |
1393 oldValue = self.dict[op.name] |
1372 oldValue = self.dict[op.name] |
1394 except KeyError: |
1373 except KeyError: |
1395 oldValue = "" |
1374 oldValue = "" |
1396 |
1375 |
1397 newValue = op.Apply(oldValue) |
1376 try: |
|
1377 newValue = op.Apply(oldValue) |
|
1378 except BadToolValue, e: |
|
1379 unfound_values.append(str(e)) |
|
1380 newValue = "NO_VALUE_FOR_" + op.name |
|
1381 |
1398 self.dict[op.name] = newValue |
1382 self.dict[op.name] = newValue |
1399 |
1383 |
1400 if self.gathertools: |
1384 if self.gathertools: |
1401 if op.type == "tool" and op.versionCommand and op.versionResult: |
1385 if op.type == "tool" and op.versionCommand and op.versionResult: |
1402 tools[op.name] = Tool(op.name, newValue, op.versionCommand, op.versionResult, configName, log = self.raptor) |
1386 tools[op.name] = Tool(op.name, newValue, op.versionCommand, op.versionResult, configName) |
1403 |
1387 |
|
1388 if len(unfound_values) > 0: |
|
1389 raise UninitialisedVariableException("\n".join(unfound_values)) |
1404 |
1390 |
1405 if self.gathertools: |
1391 if self.gathertools: |
1406 self.tools = tools.values() |
1392 self.tools = tools.values() |
1407 else: |
1393 else: |
1408 self.tools=[] |
1394 self.tools=[] |
1464 |
1450 |
1465 returns the newly expanded string.""" |
1451 returns the newly expanded string.""" |
1466 |
1452 |
1467 refs = Evaluator.refRegex.findall(value) |
1453 refs = Evaluator.refRegex.findall(value) |
1468 |
1454 |
|
1455 # store up all the unset variables before raising an exception |
|
1456 # to allow us to find them all |
|
1457 unset_variables = [] |
|
1458 |
1469 for r in set(refs): |
1459 for r in set(refs): |
1470 expansion = None |
1460 expansion = None |
1471 |
1461 |
1472 if r in self.raptor.override: |
1462 if r in self.dict: |
1473 expansion = self.raptor.override[r] |
|
1474 elif r in self.dict: |
|
1475 expansion = self.dict[r] |
1463 expansion = self.dict[r] |
1476 else: |
1464 else: |
1477 # no expansion for $(r) |
1465 # no expansion for $(r) |
1478 self.raptor.Error("Unset variable '%s' used in spec '%s' with config '%s'", |
1466 unset_variables.append("Unset variable '%s' used in spec '%s' with config '%s'" % (r, spec, config)) |
1479 r, spec, config) |
|
1480 if expansion != None: |
1467 if expansion != None: |
1481 value = value.replace("$(" + r + ")", expansion) |
1468 value = value.replace("$(" + r + ")", expansion) |
1482 |
1469 |
|
1470 if len(unset_variables) > 0: # raise them all |
|
1471 raise UninitialisedVariableException(". ".join(unset_variables)) |
|
1472 |
1483 return value |
1473 return value |
1484 |
1474 |
1485 |
1475 |
1486 # raptor_data module functions |
1476 # raptor_data module functions |
1487 |
1477 |