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
def run(): parser = argparse.ArgumentParser( \ description="Simple builtin Rez build system") parser.add_argument("TARGET", type=str, nargs='*', help="build targets") opts = parser.parse_args() # check necessary files, load info about the build for file in ("build.rxt", ".bez.yaml"): if not os.path.isfile(file): print >> sys.stderr, "no %s file found. Stop." % file sys.exit(1) with open(".bez.yaml") as f: doc = yaml.load(f.read()) source_path = doc["source_path"] buildfile = os.path.join(source_path, "rezbuild.py") if not os.path.isfile(buildfile): print >> sys.stderr, "no rezbuild.py at %s. Stop." % source_path sys.exit(1) # run rezbuild.py:build() in python subprocess. Cannot import module here # because we're in a python env configured for rez, not the build code = \ """ stream=open("%(buildfile)s") env={} exec stream in env env["build"]("%(srcpath)s","%(bldpath)s","%(instpath)s",%(targets)s) """ % dict(buildfile=buildfile, srcpath=source_path, bldpath=doc["build_path"], instpath=doc["install_path"], targets=str(opts.TARGET or None)) cli_code = textwrap.dedent(code).replace("\\", "\\\\") tmpdir_manager = TempDirs(config.tmpdir, prefix="bez_") bezfile = os.path.join(tmpdir_manager.mkdtemp(), "bezfile") with open(bezfile, "w") as fd: fd.write(cli_code) print "executing rezbuild.py..." cmd = ["python", bezfile] p = subprocess.Popen(cmd) p.wait() tmpdir_manager.clear() sys.exit(p.returncode)
def run(): parser = argparse.ArgumentParser( \ description="Simple builtin Rez build system") parser.add_argument("TARGET", type=str, nargs='*', help="build targets") opts = parser.parse_args() # check necessary files, load info about the build for file in ("build.rxt", ".bez.yaml"): if not os.path.isfile(file): print("no %s file found. Stop." % file, file=sys.stderr) sys.exit(1) with open(".bez.yaml") as f: doc = yaml.load(f.read()) source_path = doc["source_path"] buildfile = os.path.join(source_path, "rezbuild.py") if not os.path.isfile(buildfile): print("no rezbuild.py at %s. Stop." % source_path, file=sys.stderr) sys.exit(1) # run rezbuild.py:build() in python subprocess. Cannot import module here # because we're in a python env configured for rez, not the build code = """\ from __future__ import print_function with open("%(buildfile)s") as stream: env={} exec(compile(stream.read(), stream.name, 'exec'), env) buildfunc = env.get("build") if not buildfunc: import sys print("Did not find function 'build' in rezbuild.py", file=sys.stderr) sys.exit(1) kwargs = dict(source_path="%(srcpath)s", build_path="%(bldpath)s", install_path="%(instpath)s", targets=%(targets)s, build_args=%(build_args)s) import inspect args = inspect.getargspec(buildfunc).args kwargs = {k: v for k, v in kwargs.items() if k in args} buildfunc(**kwargs) """ % dict(buildfile=buildfile, srcpath=source_path, bldpath=doc["build_path"], instpath=doc["install_path"], targets=str(opts.TARGET or None), build_args=str(doc.get("build_args") or [])) cli_code = textwrap.dedent(code).replace("\\", "\\\\") tmpdir_manager = TempDirs(config.tmpdir, prefix="bez_") bezfile = os.path.join(tmpdir_manager.mkdtemp(), "bezfile") with open(bezfile, "w") as fd: fd.write(cli_code) print("executing rezbuild.py...") cmd = [sys.executable, bezfile] p = subprocess.Popen(cmd) p.wait() tmpdir_manager.clear() sys.exit(p.returncode)
def run(self, *args): """Invoke the wrapped script. Returns: Return code of the command, or 0 if the command is not run. """ from rez.vendor import argparse prefix_char = config.suite_alias_prefix_char parser = argparse.ArgumentParser(prog=self.tool_name, prefix_chars=prefix_char) def _add_argument(*nargs, **kwargs): nargs_ = [] for narg in nargs: nargs_.append(narg.replace('=', prefix_char)) parser.add_argument(*nargs_, **kwargs) _add_argument("=a", "==about", action="store_true", help="print information about the tool") _add_argument( "=i", "==interactive", action="store_true", help="launch an interactive shell within the tool's configured " "environment") _add_argument("==versions", action="store_true", help="list versions of package providing this tool") _add_argument( "=c", "==command", type=str, nargs='+', metavar=("COMMAND", "ARG"), help="read commands from string, rather than executing the tool") _add_argument( "=s", "==stdin", action="store_true", help= "read commands from standard input, rather than executing the tool" ) _add_argument("=p", "==patch", type=str, nargs='*', metavar="PKG", help="run the tool in a patched environment") _add_argument( "==strict", action="store_true", help="strict patching. Ignored if ++patch is not present") _add_argument("==nl", "==no-local", dest="no_local", action="store_true", help="don't load local packages when patching") _add_argument( "==peek", action="store_true", help="diff against the tool's context and a re-resolved copy - " "this shows how 'stale' the context is") _add_argument("=v", "==verbose", action="count", default=0, help="verbose mode, repeat for more verbosity") _add_argument( "=q", "==quiet", action="store_true", help="hide welcome message when entering interactive mode") opts, tool_args = parser.parse_known_args(args) # print info if opts.about: return self.print_about() elif opts.versions: return self.print_package_versions() elif opts.peek: return self.peek() # patching context = self.context if opts.patch is not None: new_request = opts.patch request = context.get_patched_request(new_request, strict=opts.strict) config.remove_override("quiet") pkg_paths = (config.nonlocal_packages_path if opts.no_local else None) context = ResolvedContext(request, package_paths=pkg_paths, verbosity=opts.verbose) # reapply quiet mode (see cli.forward) if "REZ_QUIET" not in os.environ: config.override("quiet", True) if opts.stdin: # generally shells will behave as though the '-s' flag was not present # when no stdin is available. So here we replicate this behaviour. import select if not select.select([sys.stdin], [], [], 0.0)[0]: opts.stdin = False # construct command cmd = None if opts.command: cmd = opts.command elif opts.interactive: label = self.context_name if opts.patch: label += '*' config.override("prompt", "%s>" % label) cmd = None else: cmd = [self.tool_name] + tool_args retcode, _, _ = context.execute_shell(command=cmd, stdin=opts.stdin, quiet=opts.quiet, block=True) return retcode
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)
def command(opts, parser, extra_arg_groups=None): from rez.cli._util import subcommands import os import re # get comp info from environment variables comp_line = os.getenv("COMP_LINE", "") comp_point = os.getenv("COMP_POINT", "") try: comp_point = int(comp_point) except: comp_point = len(comp_line) last_word = comp_line.split()[-1] if comp_line.endswith(last_word): prefix = last_word else: prefix = None def _pop_arg(l, p): words = l.split() arg = None if words: arg = words[0] l_ = l.lstrip() p -= (len(l) - len(l_) + len(arg)) l = l_[len(arg):] return l, p, arg return l, p, arg # determine subcommand, possibly give subcommand completion subcommand = None comp_line, comp_point, cmd = _pop_arg(comp_line, comp_point) if cmd in ("rez", "rezolve"): comp_line, comp_point, arg = _pop_arg(comp_line, comp_point) if arg: if prefix != arg: subcommand = arg else: subcommand = cmd.split("-", 1)[-1] if subcommand is None: cmds = [k for k, v in subcommands.items() if not v.get("hidden")] if prefix: cmds = (x for x in cmds if x.startswith(prefix)) print(" ".join(cmds)) if subcommand not in subcommands: return # replace '--' with special '--N#' flag so that subcommands can specify # custom completions. regex = re.compile("\s--\s") ddashes = regex.findall(comp_line) for i, ddash in enumerate(ddashes): j = comp_line.find(ddash) while comp_line[j] != "-": j += 1 j += 2 s = "N%d" % i comp_line = comp_line[:j] + s + comp_line[j:] if comp_point >= j: comp_point += len(s) # create parser for subcommand from rez.backport.importlib import import_module module_name = "rez.cli.%s" % subcommand mod = import_module(module_name) parser = argparse.ArgumentParser() mod.setup_parser(parser, completions=True) # have to massage input a little so argcomplete behaves cmd = "rez-%s" % subcommand comp_line = cmd + comp_line comp_point += len(cmd) # generate the completions from rez.cli._complete_util import RezCompletionFinder completer = RezCompletionFinder(parser=parser, comp_line=comp_line, comp_point=comp_point) words = completer.completions print(' '.join(words))