def findFlavors(self, productName, versions=None): """ return a list of flavors supported for the given product. An empty list is returned if the product is not declared or the given version is not declared. @param productName : the name of the product to fine @param versions : the versions to search for. If None, all versions will be considered. @return string[] : """ if versions is None: versions = self.findVersions(productName) if not isinstance(versions, list): versions = [versions] out = [] for version in versions: vfile = self._versionFile(productName, version) vfile = VersionFile(vfile, productName, version) flavors = vfile.getFlavors() for f in flavors: if f not in out: out.append(f) return out
def assignTag(self, tag, productName, version, flavors=None): """ assign a tag to a given product. @param tag : the name of the tag to assign. If the name is prepended with the "user:"******""" if isinstance(tag, str): tag = eups.tags.Tag(tag) vf = VersionFile(self._versionFile(productName, version)) declaredFlavors = vf.getFlavors() if len(declaredFlavors) == 0: raise ProductNotFound(productName, version) if flavors is None: flavors = list(declaredFlavors) elif not isinstance(flavors, list): flavors = [flavors] else: flavors = list(flavors) # make a copy; we're gonna mess with it if len(flavors) == 0: flavors = list(declaredFlavors) # reduce the list of flavors to ones actually declared for i in xrange(len(flavors)): flavor = flavors.pop(0) if flavor in declaredFlavors and flavor not in flavors: flavors.append(flavor) if len(flavors) == 0: raise ProductNotFound( productName, version, msg="Requested flavors not declared for %s %s" % (productName, version)) if tag.isUser(): if not self._getUserTagDb(): raise RuntimeError( "Unable to assign user tags (user db not available)") pdir = self._productDir(productName, self._getUserTagDb()) if not os.path.exists(pdir): os.makedirs(pdir) else: pdir = self._productDir(productName) tfile = self._tagFileInDir(pdir, tag.name) tagFile = ChainFile(tfile, productName, tag.name) tagFile.setVersion(version, flavors) tagFile.write()
def assignTag(self, tag, productName, version, flavors=None): """ assign a tag to a given product. @param tag : the name of the tag to assign. If the name is prepended with the "user:"******""" if isinstance(tag, str): tag = eups.tags.Tag(tag) vf = VersionFile(self._versionFile(productName, version)) declaredFlavors = vf.getFlavors() if len(declaredFlavors) == 0: raise ProductNotFound(productName, version) if flavors is None: flavors = list(declaredFlavors) elif not isinstance(flavors, list): flavors = [flavors] else: flavors = list(flavors) # make a copy; we're gonna mess with it if len(flavors) == 0: flavors = list(declaredFlavors) # reduce the list of flavors to ones actually declared for i in xrange(len(flavors)): flavor = flavors.pop(0) if flavor in declaredFlavors and flavor not in flavors: flavors.append(flavor) if len(flavors) == 0: raise ProductNotFound(productName, version, msg="Requested flavors not declared for %s %s" % (productName, version)) if tag.isUser(): if not self._getUserTagDb(): raise RuntimeError("Unable to assign user tags (user db not available)") pdir = self._productDir(productName, self._getUserTagDb()) if not os.path.exists(pdir): os.makedirs(pdir) else: pdir = self._productDir(productName) tfile = self._tagFileInDir(pdir, tag.name) tagFile = ChainFile(tfile, productName, tag.name) tagFile.setVersion(version, flavors) tagFile.write()
def declare(self, product): """ declare the given product. If a table file is not specified, a default one will be searched for (in the ups subdirectory of the install directory). @param product : the Product instance to register @throws UnderSpecifiedProduct if the name, version, and flavor are not all set """ if not isinstance(product, Product): raise RuntimeError("Database.declare(): argument not a Product:" + product) if not product.name or not product.version or not product.flavor: raise UnderSpecifiedProduct( msg="Product not fully specified: %s %s %s" % (str(product.name), str(product.version), str(product.flavor)) ) prod = product.clone().canonicalizePaths() tablefile = prod.tablefile if not tablefile: tablefile = prod.tableFileName() if not tablefile or not os.path.exists(tablefile): raise TableFileNotFound(prod.name, prod.version, prod.flavor, msg="Unable to located a table file in default location: " + tablefile) # set the basic product information pdir = self._productDir(prod.name) vfile = self._versionFileInDir(pdir, prod.version) versionFile = VersionFile(vfile, prod.name, prod.version) versionFile.addFlavor(prod.flavor, prod.dir, tablefile, prod.ups_dir) # seal the deal if not os.path.exists(pdir): os.mkdir(pdir) if prod.dir: trimDir = prod.stackRoot() if trimDir and not os.path.exists(trimDir): trimDir = None versionFile.write(trimDir) # now assign any tags for tag in prod.tags: self.assignTag(tag, prod.name, prod.version, prod.flavor)
def undeclare(self, product): """ undeclare the given Product. Only the name, version, and flavor will be paid attention to. False is returned if the product was not found in the database. @param product : the Product instance to undeclare. @return bool : False if nothing was undeclared @throws UnderSpecifiedProduct if the name, version, and flavor are not all set """ if not isinstance(product, Product): raise RuntimeError("Database.declare(): argument not a Product: " + product) if not product.name or not product.version or not product.flavor: raise UnderSpecifiedProduct( msg="Product not fully specified: %s %s %s" % (str(product.name), str(product.version), str(product.flavor)) ) pdir = self._productDir(product.name) vfile = self._versionFileInDir(pdir, product.version) if not os.path.exists(vfile): return False versionFile = VersionFile(vfile) if versionFile.hasFlavor(product.flavor): # unassign tags associated with this product tags = self.findTags(product.name, product.version, product.flavor) for tag in tags: self.unassignTag(tag, product.name, product.flavor) changed = versionFile.removeFlavor(product.flavor) if changed: versionFile.write() # do a little clean up: if we got rid of the version file, try # deleting the directory if not os.path.exists(vfile): try: os.rmdir(pdir) except: pass return changed
def isDeclared(self, productName, version=None, flavor=None): """ return true if a product is declared. @param productName : the name of the product to search for @param version : a specific version to look for. If None, return true if any version of this product is available. @param flavor : a specific platform flavor to look for. If None, return true if any flavor is supported by the product. """ pdir = self._productDir(productName) if not os.path.exists(pdir): return False if version is None: if flavor is None: return True vfiles = os.listdir(pdir) for file in vfiles: if (versionFileRe.match(file)): file = VersionFile(os.path.join(pdir,file)) vers = file.version if file.hasFlavor(flavor): return True return False else: file = self._versionFileInDir(pdir, version) if not os.path.exists(file): return False if flavor is None: return True file = VersionFile(file) return file.hasFlavor(flavor)
def findProduct(self, name, version, flavor): """ find the fully specified declared product given its name, version, and platform flavor, or None if product is not declared. @param name : the name of the desired product @param version : the desired version of the product @param flavor : the desired platform flavor @return Product : the matched product or None if not found """ vfile = self._findVersionFile(name, version) if vfile is None: return None verdata = VersionFile(vfile, name, version) product = None try: product = verdata.makeProduct(flavor, self.defStackRoot, self.dbpath) product.tags = self.findTags(name, version, flavor) except ProductNotFound: return None return product
def declare(self, product): """ declare the given product. If a table file is not specified, a default one will be searched for (in the ups subdirectory of the install directory). @param product : the Product instance to register @throws UnderSpecifiedProduct if the name, version, and flavor are not all set """ if not isinstance(product, Product): raise RuntimeError("Database.declare(): argument not a Product:" + product) if not product.name or not product.version or not product.flavor: raise UnderSpecifiedProduct( msg="Product not fully specified: %s %s %s" % (str(product.name), str(product.version), str(product.flavor))) prod = product.clone().canonicalizePaths() tablefile = prod.tablefile if not tablefile: tablefile = prod.tableFileName() if not tablefile or not os.path.exists(tablefile): raise TableFileNotFound( prod.name, prod.version, prod.flavor, msg="Unable to located a table file in default location: " + tablefile) # set the basic product information pdir = self._productDir(prod.name) vfile = self._versionFileInDir(pdir, prod.version) versionFile = VersionFile(vfile, prod.name, prod.version) versionFile.addFlavor(prod.flavor, prod.dir, tablefile, prod.ups_dir) # seal the deal if not os.path.exists(pdir): os.mkdir(pdir) if prod.dir: trimDir = prod.stackRoot() if trimDir and not os.path.exists(trimDir): trimDir = None versionFile.write(trimDir) # now assign any tags for tag in prod.tags: self.assignTag(tag, prod.name, prod.version, prod.flavor)
def undeclare(self, product): """ undeclare the given Product. Only the name, version, and flavor will be paid attention to. False is returned if the product was not found in the database. @param product : the Product instance to undeclare. @return bool : False if nothing was undeclared @throws UnderSpecifiedProduct if the name, version, and flavor are not all set """ if not isinstance(product, Product): raise RuntimeError("Database.declare(): argument not a Product: " + product) if not product.name or not product.version or not product.flavor: raise UnderSpecifiedProduct( msg="Product not fully specified: %s %s %s" % (str(product.name), str(product.version), str(product.flavor))) pdir = self._productDir(product.name) vfile = self._versionFileInDir(pdir, product.version) if not os.path.exists(vfile): return False versionFile = VersionFile(vfile) if versionFile.hasFlavor(product.flavor): # unassign tags associated with this product tags = self.findTags(product.name, product.version, product.flavor) for tag in tags: self.unassignTag(tag, product.name, product.flavor) changed = versionFile.removeFlavor(product.flavor) if changed: versionFile.write() # do a little clean up: if we got rid of the version file, try # deleting the directory if not os.path.exists(vfile): try: os.rmdir(pdir) except: pass return changed
def isDeclared(self, productName, version=None, flavor=None): """ return true if a product is declared. @param productName : the name of the product to search for @param version : a specific version to look for. If None, return true if any version of this product is available. @param flavor : a specific platform flavor to look for. If None, return true if any flavor is supported by the product. """ pdir = self._productDir(productName) if not os.path.exists(pdir): return False if version is None: if flavor is None: return True vfiles = os.listdir(pdir) for file in vfiles: if (versionFileRe.match(file)): file = VersionFile(os.path.join(pdir, file)) vers = file.version if file.hasFlavor(flavor): return True return False else: file = self._versionFileInDir(pdir, version) if not os.path.exists(file): return False if flavor is None: return True file = VersionFile(file) return file.hasFlavor(flavor)
def findProducts(self, name, versions=None, flavors=None): """ return a list of Products matching the given inputs @param name : the name of the desired product @param versions : the desired versions. If versions is None, return all declared versions of the product. @param flavors : the desired flavors. If None, return matching products of all declared flavors. @return Product[] : a list of the matching products """ if versions is None: versions = self.findVersions(name) if not isinstance(versions, list): versions = [versions] if flavors is not None and not isinstance(flavors, list): flavors = [flavors] out = {} for vers in versions: vfile = self._versionFile(name, vers) if not os.path.exists(vfile): continue vfile = VersionFile(vfile, name, vers) flavs = flavors declared = vfile.getFlavors() if flavs is None: flavs = declared out[vers] = {} for f in flavs: if f in declared: out[vers][f] = vfile.makeProduct(f, self.defStackRoot, self.dbpath) if len(out.keys()) == 0: return [] pdir = self._productDir(name) if not os.path.exists(pdir): raise RuntimeError("programmer error: product directory disappeared") # add in the tags for tag, vers, flavor in self.getTagAssignments(name): try: out[vers][flavor].tags.append(tag) except KeyError: pass # not sure why this doesn't work: # out = reduce(lambda x,y: x.extend(y), # map(lambda z: z.values(), out.values())) # out.sort(_cmp_by_verflav) # # replaced with moral equivalent: # v = map(lambda z: z.values(), out.values()) x = v[0] for y in v[1:]: x.extend(y) x.sort(_cmp_by_verflav) return x
def findProducts(self, name, versions=None, flavors=None): """ return a list of Products matching the given inputs @param name : the name of the desired product @param versions : the desired versions. If versions is None, return all declared versions of the product. @param flavors : the desired flavors. If None, return matching products of all declared flavors. @return Product[] : a list of the matching products """ if versions is None: versions = self.findVersions(name) if not isinstance(versions, list): versions = [versions] if flavors is not None and not isinstance(flavors, list): flavors = [flavors] out = {} for vers in versions: vfile = self._versionFile(name, vers) if not os.path.exists(vfile): continue vfile = VersionFile(vfile, name, vers) flavs = flavors declared = vfile.getFlavors() if flavs is None: flavs = declared out[vers] = {} for f in flavs: if f in declared: out[vers][f] = vfile.makeProduct(f, self.defStackRoot, self.dbpath) if len(out.keys()) == 0: return [] pdir = self._productDir(name) if not os.path.exists(pdir): raise RuntimeError( "programmer error: product directory disappeared") # add in the tags for tag, vers, flavor in self.getTagAssignments(name): try: out[vers][flavor].tags.append(tag) except KeyError: pass # not sure why this doesn't work: # out = reduce(lambda x,y: x.extend(y), # map(lambda z: z.values(), out.values())) # out.sort(_cmp_by_verflav) # # replaced with moral equivalent: # v = map(lambda z: z.values(), out.values()) x = v[0] for y in v[1:]: x.extend(y) x.sort(_cmp_by_verflav) return x