def getEups(): """Return a cached eups instance""" try: return getEups._eups except AttributeError: getEups._eups = Eups() return getEups._eups
def getEnvironmentPackages(): """Provide a dict of products and their versions from the environment We use EUPS to determine the version of certain products (those that don't provide a means to determine the version any other way) and to check if uninstalled packages are being used. We only report the product/version for these packages. """ try: from eups import Eups from eups.Product import Product except: from lsst.pex.logging import getDefaultLog getDefaultLog().warn("Unable to import eups, so cannot determine package versions from environment") return {} # Cache eups object since creating it can take a while global _eups if not _eups: _eups = Eups() products = _eups.findProducts(tags=["setup"]) # Get versions for things we can't determine via runtime mechanisms # XXX Should we just grab everything we can, rather than just a predetermined set? packages = {prod.name: prod.version for prod in products if prod in ENVIRONMENT} # The string 'LOCAL:' (the value of Product.LocalVersionPrefix) in the version name indicates uninstalled # code, so the version could be different than what's being reported by the runtime environment (because # we don't tend to run "scons" every time we update some python file, and even if we did sconsUtils # probably doesn't check to see if the repo is clean). for prod in products: if not prod.version.startswith(Product.LocalVersionPrefix): continue ver = prod.version gitDir = os.path.join(prod.dir, ".git") if os.path.exists(gitDir): # get the git revision and an indication if the working copy is clean revCmd = ["git", "--git-dir=" + gitDir, "--work-tree=" + prod.dir, "rev-parse", "HEAD"] diffCmd = ["git", "--no-pager", "--git-dir=" + gitDir, "--work-tree=" + prod.dir, "diff", "--patch"] try: rev = subprocess.check_output(revCmd).decode().strip() diff = subprocess.check_output(diffCmd) except: ver += "@GIT_ERROR" else: ver += "@" + rev if diff: ver += "+" + hashlib.md5(diff).hexdigest() else: ver += "@NO_GIT" packages[prod.name] = ver return packages
def getEnvironmentPackages(include_all: bool = False) -> Dict[str, str]: """Get products and their versions from the environment. Parameters ---------- include_all : `bool` If `False` only returns locally-setup packages. If `True` all set up packages are returned with a version that includes any associated non-current tags. Returns ------- packages : `dict` Keys (type `str`) are product names; values (type `str`) are their versions. Notes ----- We use EUPS to determine the version of certain products (those that don't provide a means to determine the version any other way) and to check if uninstalled packages are being used. We only report the product/version for these packages unless ``include_all`` is `True`. """ try: from eups import Eups from eups.Product import Product except ImportError: log.warning( "Unable to import eups, so cannot determine package versions from environment" ) return {} # Cache eups object since creating it can take a while global _eups if not _eups: _eups = Eups() products = _eups.findProducts(tags=["setup"]) # Get versions for things we can't determine via runtime mechanisms # XXX Should we just grab everything we can, rather than just a # predetermined set? packages = { prod.name: prod.version for prod in products if prod in ENVIRONMENT } # The string 'LOCAL:' (the value of Product.LocalVersionPrefix) in the # version name indicates uninstalled code, so the version could be # different than what's being reported by the runtime environment (because # we don't tend to run "scons" every time we update some python file, # and even if we did sconsUtils probably doesn't check to see if the repo # is clean). for prod in products: if not prod.version.startswith(Product.LocalVersionPrefix): if include_all: tags = {t for t in prod.tags if t != "current"} tag_msg = " (" + " ".join(tags) + ")" if tags else "" packages[prod.name] = prod.version + tag_msg continue ver = prod.version gitDir = os.path.join(prod.dir, ".git") if os.path.exists(gitDir): # get the git revision and an indication if the working copy is # clean revCmd = [ "git", "--git-dir=" + gitDir, "--work-tree=" + prod.dir, "rev-parse", "HEAD" ] diffCmd = [ "git", "--no-pager", "--git-dir=" + gitDir, "--work-tree=" + prod.dir, "diff", "--patch", ] try: rev = subprocess.check_output(revCmd).decode().strip() diff = subprocess.check_output(diffCmd) except Exception: ver += "@GIT_ERROR" else: ver += "@" + rev if diff: ver += "+" + hashlib.md5(diff).hexdigest() else: ver += "@NO_GIT" packages[prod.name] = ver return packages
def __init__(self, pkgroots, options=None, eupsenv=None, installFlavor=None, distribClasses=None, override=None, allowEmptyPkgroot=False, verbosity=None, log=sys.stderr): """ @param pkgroots the base URLs for the distribution repositories. This can either be a list or a pipe-delimited ("|") string. @param options a dictionary of named options that are used to fine- tune the behavior of the repositories. These are passed onto the constructors for the underlying Reposistory classes. @param eupsenv an instance of a Eups class containing the Eups environment to assume @param installFlavor the desired flavor any install requests @param distribClasses a dictionary by name of the Distrib classes to support. This will augmented by those specified by a server. @param override a dictionary of server configuration parameters that should override the configuration received from each server. @param allowEmptyPkgroot we are creating a distribution, so it's OK for pkgroot to be empty @param verbosity if > 0, print status messages; the higher the number, the more messages that are printed (default is the value of eupsenv.verbose). @param log the destination for status messages (default: sys.stderr) """ if isinstance(pkgroots, str): pkgroots = map(lambda p: p.strip(), pkgroots.split("|")) if not allowEmptyPkgroot and len(pkgroots) == 0: raise EupsException("No package servers to query; set -r or $EUPS_PKGROOT") # the Eups environment self.eups = eupsenv if not self.eups: self.eups = Eups() self.verbose = verbosity if self.verbose is None: self.verbose = self.eups.verbose self.log = log if self.log is None: self.log = sys.stdout if not distribClasses: distribClasses = {} # the list of repository base URLs self.pkgroots = [] # a lookup of Repository instances by its base URL self.repos = {} # the preferred installation flavor self.flavor = installFlavor if not self.flavor: self.flavor = self.eups.flavor df = DistribFactory(self.eups) for name in distribClasses.keys(): # note: this will override the server's recommendation # if we want change this, use: # if not df.supportsName(name): # df.register(distribClasses[name], name) # df.register(distribClasses[name], name) for pkgroot in pkgroots: # if pkgroot == None: # ds = None # else: # ds = ServerConf.makeServer(pkgroot, eupsenv=eupsenv, # override=override, # verbosity=self.eups.verbose) # try: dist = Repository(self.eups, pkgroot, options=options, flavor=installFlavor, distFactory=df, verbosity=self.eups.verbose) self.pkgroots += [pkgroot] self.repos[pkgroot] = dist except ImportError, e: msg = "Unable to use server %s: \"%s\"" % (pkgroot, e) if self.eups.force: print >> self.log, msg + "; continuing" else: raise RuntimeError(msg + ". Remove server from PKGROOT or use force")