def tableFileName(self): """ return the assumed path to the product's table file. This is self.tablefile unless it is null; in this case, a default path based on self.dir (namely, {self.dir}/ups/{self.name}.table) is returned). None is returned if the product is known not to have an associated table file. """ if self.tablefile is not None and \ not utils.isRealFilename(self.tablefile): return None elif self.tablefile is None or not os.path.isabs(self.tablefile): clone = self.clone().resolvePaths() if utils.isRealFilename(clone.tablefile): return clone.tablefile return self.tablefile
def canonicalizePaths(self): """ convert any internal absolute paths to ones relative to a root directories. This is appropriate for storage into database version files: without absolute paths, the files can be moved to another place on a filesystem without invalidating internal data. @param strict raise an exception if an absolute path remains. """ sl = os.path.sep root = self.stackRoot() if not utils.isRealFilename(root): return self if self.tablefile is None: if self.name: self.tablefile = self.name+".table" if self.ups_dir is None and utils.isRealFilename(self.dir): self.ups_dir = os.path.join(self.dir, "ups") # transform tablefile if utils.isRealFilename(self.tablefile) and os.path.isabs(self.tablefile): if utils.isRealFilename(self.db) and \ self.tablefile.startswith(self.db): if self.ups_dir is None: self.ups_dir = os.path.join("$UPS_DB", os.path.dirname(self.tablefile)[len(self.db)+1:]) self.tablefile = os.path.basename(self.tablefile) else: self.tablefile = os.path.join("$UPS_DB", self.ups_dir[len(self.db)+1:]) elif utils.isRealFilename(self.ups_dir): if self.tablefile.startswith(self.ups_dir+sl): # a relative tablefile path is relative to ups_dir, # if set. self.tablefile = self.tablefile[len(self.ups_dir)+1:] elif utils.isRealFilename(self.dir) and \ self.tablefile.startswith(self.dir+sl): # when ups_dir is not set, relative tablefile is relative to # the product dir self.tablefile = self.tablefile[len(self.dir)+1:] # transform ups_dir if utils.isRealFilename(self.ups_dir) and os.path.isabs(self.ups_dir): if utils.isRealFilename(self.dir) and self.ups_dir.startswith(self.dir+sl): # relative ups_dir path is relative to product dir self.ups_dir = self.ups_dir[len(self.dir)+1:] elif utils.isRealFilename(self.dir) and self.ups_dir == self.dir: self.ups_dir = "none" elif utils.isRealFilename(self.db) and self.ups_dir(startswith(self.db+sl)): self.ups_dir = os.path.join("$UPS_DB", self.ups_dir[len(self.db)+1:]) elif utils.isRealFilename(self.db) and self.ups_dir == self.db: self.ups_dir = "$UPS_DB" # transform installation dir if utils.isRealFilename(self.dir) and self.dir.startswith(root+sl): # relative ups_dir path is relative to stack root self.dir = self.dir[len(root+sl):] return self
def resolvePaths(self, strict=False): """ Update the internal data so that all paths in the product data are resolved to absolute paths. This is desirable for caching this product in a ProductStack (ProductStack.addProduct() calls this internally). Path resolution is carried out according to the following rules: * A value of "none" indicates that the path explicitly does not have a logical value. For example, for table_file, the product does not have a table file to set up the product. For productDir, the product is not formally installed anywhere. * A value of None indicates that the path can be reset to a normalized default when written out. * Any path can be absolutely specified (though they may get normalized when written out). * If productDir is relative, it is assumed to be relative to the base directory of the software stack (not known to this class). * If the ups_dir is relative, it is assumed to be relative to the product installation directory, productDir. * If the table file is relative, it is assumed to be relative to the ups_dir directory. If the ups_dir is "none" or None, then the table file is relative to productDir. * The path may include symbolic path "macro"--a path with a context-specific value. These macros have the form $name, and most have restrictions on where in the value it can appear (i.e. all but $FLAVOR may only appear at the start of the path). Some restrictions also apply as to within which path a macro may appear. The supported macros are: $PROD_ROOT -- the absolute path to the default root directory where products are installed by default--i.e. the value of the EUPS path directory where it is registered. This can only appear at the start of the path. $FLAVOR -- the value of the product's flavor. $PROD_DIR -- the fully resolved value of productDir; this macro cannot appear in the productDir value. This can only appear at the start of the path. $UPS_DIR -- the fully resolved value of ups_dir. This can only appear at the start of the path. $UPS_DB -- the path to the EUPS database directory path (which typically ends with the name "ups_db"). This can only appear at the start of the path. @param strict raise an exception if the non-none product directory or table file cannot be resolved. """ root = self.stackRoot() macrodata = { "FLAVOR": self.flavor, "PROD_ROOT": root, "UPS_DB": self.db } if utils.isRealFilename(self.dir) and not os.path.isabs(self.dir): if not self.dir.startswith("$PROD_") and \ not self.dir.startswith("$UPS_") and not root in (None, "none"): self.dir = os.path.join(root, self.dir) self.dir = self._resolve(self.dir, macrodata) if strict and not os.path.isabs(self.dir): raise ValueError("product dir unresolvable: " + self.dir) macrodata["PROD_DIR"] = self.dir if utils.isRealFilename(self.ups_dir) and not os.path.isabs(self.ups_dir): if not self.ups_dir.startswith("$PROD_") and \ not self.ups_dir.startswith("$UPS_") and not self.dir in (None, "none"): self.ups_dir = os.path.join(self.dir, self.ups_dir) self.ups_dir = self._resolve(self.ups_dir, macrodata) # if strict and not os.path.isabs(self.dir): # raise ValueError("product ups dir unresolvable: "+self.ups_dir) macrodata["UPS_DIR"] = self.ups_dir if self.tablefile is None and self.name and \ (utils.isRealFilename(self.dir) or \ utils.isRealFilename(self.ups_dir)): self.tablefile = "%s.table" % self.name if utils.isRealFilename(self.tablefile) and not os.path.isabs(self.tablefile): if not self.tablefile.startswith("$PROD_") and \ not self.tablefile.startswith("$UPS_"): if self.ups_dir is None and utils.isRealFilename(self.dir): self.ups_dir = os.path.join(self.dir, "ups") if utils.isRealFilename(self.ups_dir): ntable = os.path.join(self.ups_dir, self.tablefile) # # OK, be nice. Look relative to eupsPathDir too. This is needed due to # malformed .version files (fixed in r10329) # if root: n2table = os.path.join(root, self.tablefile) if os.path.exists(ntable): self.tablefile = ntable elif root and os.path.exists(n2table): self.tablefile = n2table else: self.tablefile = ntable # Hack for now to make tests pass when table file doesn't exist elif utils.isRealFilename(self.dir): if self.ups_dir is None: self.tablefile = os.path.join(self.dir,"ups", self.tablefile) else: self.tablefile = os.path.join(self.dir, self.tablefile) self.tablefile = self._resolve(self.tablefile, macrodata) if strict and not os.path.isabs(self.tablefile): raise ValueError("product table file unresolvable: " + self.tablefile) # one last try: if utils.isRealFilename(self.dir) and self.dir.find('$') >= 0: self.dir = self._resolve(self.dir, macrodata, skip="PROD_DIR") macrodata["PROD_DIR"] = self.dir if utils.isRealFilename(self.tablefile) and \ self.tablefile.find('$') >= 0: self.tablefile = self._resolve(self.tablefile, macrodata) return self