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 getChainFile(self, tag, productName, searchUserDB=False): """ return the ChainFile for the version name of the product that has the given tag assigned to it. None is return if the tag is not assigned to any version. ProductNotFound is raised if no version of the product is declared. @param tag the string name for the tag. A user tag must be prepended by a "user:"******""" pdir = self._productDir(productName) if not os.path.exists(pdir): raise ProductNotFound(productName, stack=self.dbpath) if is_string(tag): tag = eups.tags.Tag(tag) pdirs = [] if searchUserDB and tag.isUser(): for d in self._getUserTagDb(values=True): if d: pdirs.append(self._productDir(productName, d)) else: pdirs.append(pdir) for pdir in pdirs: tfile = self._tagFileInDir(pdir, tag.name) if os.path.exists(tfile): return ChainFile(tfile) return None
def makeProduct(self, flavor, eupsPathDir=None, dbpath=None): """ create a Product instance for the given flavor. If the product has not been declared for the flavor, a ProductNotFound exception is raised. @param flavor : the desired flavor for the Product. @param eupsPathDir : the product stack path to assume that product is installed under. If the product install directory is a relative path (product.dir), this eupsPathDir will be prepended in the output. If None, no alterations of the product install directory will be done. @param dbpath : the product database directory to store into the output product.db attribute. If None, it will default to eupsPathDir/ups_db; if eupsPathDir is None, the product.db field will not be set. @return Product : a Product instance representing the product data """ if flavor not in self.info: raise ProductNotFound(self.name, self.version, flavor) if eupsPathDir and not dbpath: dbpath = os.path.join(eupsPathDir, "ups_db") info = self.info[flavor] out = Product(self.name, self.version, flavor, info.get("productDir"), info.get("table_file"), db=dbpath, ups_dir=info.get("ups_dir")) out.resolvePaths() return out
def getProduct(self, version, dbpath=None, flavor=None): """ return the Product of the requested version or None if not found. This returned Product's db attribute will be set to None. @param version : the desired version @param dbpath a database path to set on the returned product @param flavor a platform flavor to set on the returned product @return the product description as a Product instance """ try: versdata = self.versions[version] tags = map(lambda item: item[0], filter(lambda x: x[1] == version, self.tags.items())) out = Product( self.name, version, flavor, versdata[0], # the install directory versdata[1], # the table file tags, dbpath) if versdata[2]: out._table = versdata[2] return out except KeyError: raise ProductNotFound(self.name, version)
def createTaggedRelease(self, tag, product, version=None, flavor=None, distrib=None): """ create and release a named collection of products based on the known dependencies of a given product. @param serverRoot the root directory of a local server distribution tree @param tag the name to give to this tagged release. @param product the name of the product to create @param version the version of the product to create. (Default: the version marked current in the EUPS db) @param flavor the flavor to associate with this release (Default: "generic") @param distrib a Distrib instance to use to determine which products to include. If not provided, a default will be used. """ if distrib is not None and not isinstance(distrib, Distrib): raise TypeError("distrib parameter not a Distrib instance") validTags = self.getSupportedTags() if tag in validTags: if not self.eups.force: raise EupsException("Can't over-write existing tagged release "+ "without --force") elif self.verbose > 0: print("Over-writing existing tagged release for", tag, file=self.log) elif self.verbose > 0: print("Creating new tagged release for", tag, file=self.log) if not flavor: flavor = "generic" if not version: version = self.eups.findPreferredProduct(product) if version: version = version.version if not version: msg = "No local version of %s found" % product raise ProductNotFound(product, msg) if distribTypeName: distrib = \ self.distFactory.createDistribByName(distribTypeName, options=self.options, verbosity=self.verbose, log=self.log) else: distrib = DefaultDistrib(self.eups, self.distServer, self.flavor, options=self.options, verbosity=self.verbose, log=self.log) release = distrib.createTaggedRelease(serverRoot, tag, product, version, flavor) distrib.writeTaggedRelease(self.pkgroot, tag, products, flavor, self.eups.flavor)
def assignTag(self, tag, version, file=None): """ assign the given tag to a version of the product. @param tag : the tag name being assigned @param version : the name of the version being assigned the tag @param file : the file to record the tagging information to. If None, it will not get recorded. """ if not self.hasVersion(version): raise ProductNotFound(self.name, version) tag = str(tag) self.tags[tag] = version
def getProduct(self, name, version, flavor): """ lookup and return a Product description given the product name, flavor, and version. All parameters must be provided. @param name : the product name @param version : the desired version name @param flavor : the desired platform flavor @return Product : the requested product """ try: out = self.lookup[flavor][name].getProduct(version) out.flavor = flavor out.db = self.dbpath out._prodStack = self return out except KeyError: raise ProductNotFound(name, version, flavor)
def findTags(self, productName, version, flavor): """ return a list of tags for a given product. An empty list is returned if no tags are assigned. ProductNotFound is raised if no version of the product is declared. @param productName : the name of the desired product @param version : the desired version of the product @param flavor : the desired platform flavor """ pdir = self._productDir(productName) if not os.path.exists(pdir): raise ProductNotFound(productName, version, flavor, self.dbpath) tags = self._findTagsInDir(pdir, productName, version, flavor) if self._getUserTagDb(): udir = self._productDir(productName, self._getUserTagDb()) if os.path.isdir(udir): tags.extend("user:" + t for t in self._findTagsInDir( udir, productName, version, flavor)) return tags
def assignTag(self, tag, product, version, flavors=None): """ assign a tag to a given version of a product. If tag does not start with "user:"******"user:"******""" if flavors is None: return self.assignTag(tag, product, version, list(self.lookup.keys())) notfound = True if not isinstance(flavors, list): flavors = [flavors] for flavor in flavors: try: self.lookup[flavor][product].assignTag(tag, version) # if tag.startswith(userPrefix): # self._setUserTag(flavor, tag, product, version) notfound = False except KeyError: pass if notfound: raise ProductNotFound(product, version, flavors, self.dbpath) self._flavorsUpdated(flavors) if self.autosave: self.save(flavors)
def loadTableFor(self, version, table=None): """ cache the parsed contents of the table file. If table is not None, it will be taken as the Table instance representing the already parsed contents; otherwise, the table will be loaded from the table file path. @param version the version of the product to load @param table an instance of Table to accept as the loaded contents """ try: verdata = self.versions[version] if not table: if not utils.isRealFilename(verdata[1]): return if not os.path.exists(verdata[1]): raise TableFileNotFound(verdata[1], self.name, version) prod = self.getProduct(version) table = Table(verdata[1]).expandEupsVariables(prod) self.versions[version] = (verdata[0], verdata[1], table) except KeyError: raise ProductNotFound(self.name, version)
def loadTableFor(self, productName, version, flavor, table=None): """ cache the parsed contents of the table file for a given product. If table is not None, it will be taken as the Table instance representing the already parsed contents; otherwise, the table will be loaded from the table file path. @param productName the name of the desired product @param version the version of the product to load @param flavor the product's flavor. If none, load all tables. @param table an instance of Table to accept as the loaded contents """ try: if not table: # get a fully parsed, resolved table prod = self.getProduct(productName, version, flavor) table = prod.getTable() self.lookup[flavor][productName].loadTableFor(version, table) self._flavorsUpdated(flavor) except KeyError: raise ProductNotFound(productName, version, flavor)