Пример #1
0
def getEups():
    """Return a cached eups instance"""
    try:
        return getEups._eups
    except AttributeError:
        getEups._eups = Eups()
        return getEups._eups
Пример #2
0
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
Пример #3
0
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
Пример #4
0
    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")