Beispiel #1
0
def _bind_package(name, path=None, version_range=None, bind_args=None,
                  quiet=False):
    bindfile = find_bind_module(name, verbose=(not quiet))
    if not bindfile:
        raise RezBindError("Bind module not found for '%s'" % name)

    # load the bind module
    namespace = {}
    with open(bindfile) as stream:
        exec(compile(stream.read(), stream.name, 'exec'), namespace)

    # parse bind module params
    bind_parser = argparse.ArgumentParser(prog="rez bind %s" % name,
                                          description="%s bind module" % name)
    parserfunc = namespace.get("setup_parser")
    if parserfunc:
        parserfunc(bind_parser)
    bind_opts = bind_parser.parse_args(bind_args or [])

    # make the package
    install_path = path or config.local_packages_path

    if not quiet:
        print("creating package '%s' in %s..." % (name, install_path))

    bindfunc = namespace.get("bind")
    if not bindfunc:
        raise RezBindError("'bind' function missing in %s" % bindfile)

    variants = bindfunc(path=install_path,
                        version_range=version_range,
                        opts=bind_opts,
                        parser=bind_parser)

    return variants
Beispiel #2
0
def extract_version(exepath, version_arg, word_index=-1, version_rank=3):
    """Run an executable and get the program version.

    Args:
        exepath: Filepath to executable.
        version_arg: Arg to pass to program, eg "-V". Can also be a list.
        word_index: Expect the Nth word of output to be the version.
        version_rank: Cap the version to this many tokens.

    Returns:
        `Version` object.
    """
    if isinstance(version_arg, basestring):
        version_arg = [version_arg]
    args = [exepath] + version_arg

    stdout, stderr, returncode = _run_command(args)
    if returncode:
        raise RezBindError("failed to execute %s: %s\n(error code %d)" %
                           (exepath, stderr, returncode))

    stdout = stdout.strip().split('\n')[0].strip()
    log("extracting version from output: '%s'" % stdout)

    try:
        strver = stdout.split()[word_index]
        toks = strver.replace('.', ' ').replace('-', ' ').split()
        strver = '.'.join(toks[:version_rank])
        version = Version(strver)
    except Exception as e:
        raise RezBindError("failed to parse version from output '%s': %s" %
                           (stdout, str(e)))

    log("extracted version: '%s'" % str(version))
    return version
Beispiel #3
0
def copy_module(name, destpath):
    success, out, err = run_python_command([
        "import %s" % name,
        "print %s.__path__[0] if hasattr(%s, '__path__') else ''" %
        (name, name)
    ])

    if out:
        srcpath = out
        shutil.copytree(srcpath, os.path.join(destpath, name))
    else:
        success, out, err = run_python_command(
            ["import %s" % name,
             "print %s.__file__" % name])
        if not success:
            raise RezBindError("Couldn't locate module %s: %s" % (name, err))

        srcfile = out
        dirpart, ext = os.path.splitext(srcfile)

        if ext == ".pyc":
            pyfile = dirpart + ".py"
            if os.path.exists(pyfile):
                srcfile = pyfile

        destfile = os.path.join(destpath, os.path.basename(srcfile))
        shutil.copy2(srcfile, destfile)
Beispiel #4
0
def get_version_in_python(name, commands):
    success, out, err = run_python_command(commands)
    if not success or not out:
        raise RezBindError("Couldn't determine version of module %s: %s" %
                           (name, err))
    version = out
    return version
Beispiel #5
0
def bind(path, version_range=None, opts=None, parser=None):
    exe_path = getattr(opts, 'exe', None)

    # gcc
    gcc_path = find_exe('gcc', filepath=exe_path)
    gcc_version = extract_version(gcc_path, ['-dumpfullversion', '-dumpversion'])
    log("binding gcc: %s" % gcc_path)

    # g++
    gpp_path = find_exe('g++', filepath=exe_path)
    gpp_version = extract_version(gpp_path, ['-dumpfullversion', '-dumpversion'])
    log("binding g++: %s" % gpp_path)

    if gcc_version != gpp_version:
        raise RezBindError("gcc version different than g++ can not continue")

    # create directories and symlink gcc and g++
    def make_root(variant, root):
        bin_path = make_dirs(root, 'bin')

        gcc_link_path = os.path.join(bin_path, 'gcc')
        platform_.symlink(gcc_path, gcc_link_path)

        gpp_link_path = os.path.join(bin_path, 'g++')
        platform_.symlink(gpp_path, gpp_link_path)

    with make_package('gcc', path, make_root=make_root) as pkg:
        pkg.version = gcc_version
        pkg.tools = ['gcc', 'g++']
        pkg.commands = commands
        pkg.variants = [system.variant]

    return pkg.installed_variants
Beispiel #6
0
def check_version(version, range_=None):
    """Check that the found software version is within supplied range.

    Args:
        version: Version of the package as a Version object.
        range_: Allowable version range as a VersionRange object.
    """
    if range_ and version not in range_:
        raise RezBindError("found version %s is not within range %s" %
                           (str(version), str(range_)))
Beispiel #7
0
def find_exe(name, filepath=None):
    """Find an executable.

    Args:
        name: Name of the program, eg 'python'.
        filepath: Path to executable, a search is performed if None.

    Returns:
        Path to the executable if found, otherwise an error is raised.
    """
    if filepath:
        if not os.path.exists(filepath):
            open(filepath)  # raise IOError
        elif not os.path.isfile(filepath):
            raise RezBindError("not a file: %s" % filepath)
    else:
        filepath = which(name)
        if not filepath:
            raise RezBindError("could not find executable: %s" % name)

    return filepath
Beispiel #8
0
def command(opts, parser, extra_arg_groups=None):
    from rez.config import config
    from rez.exceptions import RezBindError
    from rez import module_root_path
    from rez.util import get_close_pkgs
    from rez.utils.formatting import columnise, PackageRequest
    from rez.vendor.version.requirement import VersionedObject
    import os.path
    import os
    import sys

    # gather the params
    install_path = (config.local_packages_path
                    if opts.install_path is None else opts.install_path)
    req = PackageRequest(opts.PKG)
    name = req.name
    version_range = None if req.range.is_any() else req.range
    if req.conflict:
        parser.error("PKG cannot be a conflict requirement")

    # find the bind module
    builtin_path = os.path.join(module_root_path, "bind")
    searchpaths = config.bind_module_path + [builtin_path]
    bindfile = None
    bindnames = {}

    for path in searchpaths:
        if opts.verbose:
            print "searching %s..." % path
        if not os.path.isdir(path):
            continue

        filename = os.path.join(path, name + ".py")
        if os.path.isfile(filename):
            if opts.search:
                print filename
                sys.exit(0)
            else:
                bindfile = filename
                break
        else:
            for filename in os.listdir(path):
                fpath = os.path.join(path, filename)
                fname, ext = os.path.splitext(filename)
                if os.path.isfile(fpath) and ext == ".py" \
                        and not fname.startswith('_'):
                    bindnames[fname] = fpath

    if not bindfile:
        fuzzy_matches = get_close_pkgs(name, bindnames.keys())

        if opts.search:
            if fuzzy_matches:
                rows = [(x[0], bindnames[x[0]]) for x in fuzzy_matches]
                print "'%s' not found. Close matches:" % name
                print '\n'.join(columnise(rows))
            else:
                print "No matches."
            sys.exit(0)
        else:
            msg = "bind module not found for '%s'" % name
            if fuzzy_matches:
                matches_s = ', '.join(x[0] for x in fuzzy_matches)
                msg += "\ndid you mean one of: %s" % matches_s

            raise RezBindError(msg)

    # load the bind module
    stream = open(bindfile)
    namespace = {}
    exec stream in namespace

    # parse bind module params
    bind_parser = argparse.ArgumentParser(prog="rez bind %s" % name,
                                          description="%s bind module" % name)
    parserfunc = namespace.get("setup_parser")
    if parserfunc:
        parserfunc(bind_parser)
    bind_opts = bind_parser.parse_args(opts.BIND_ARG)

    # make the package
    if opts.verbose:
        print "creating package '%s' in %s..." % (name, install_path)

    bindfunc = namespace.get("bind")
    if not bindfunc:
        raise RezBindError("'bind' function missing in %s" % bindfile)

    name, version = bindfunc(path=install_path,
                             version_range=version_range,
                             opts=bind_opts,
                             parser=bind_parser)

    o = VersionedObject.construct(name, version)
    print "created package '%s' in %s" % (str(o), install_path)