Пример #1
0
def _check_found(py_exe, version_text, log_invalid=True):
    """Check the Python and pip version text found.

    Args:
        py_exe (str or None): Python executable path found, if any.
        version_text (str or None): Pip version found, if any.
        log_invalid (bool): Whether to log messages if found invalid.

    Returns:
        bool: Python is OK and pip version fits against ``PIP_SPECIFIER``.
    """
    is_valid = True
    message = "Needs pip%s, but found '%s' for Python '%s'"

    if version_text is None or not py_exe:
        is_valid = False
        if log_invalid:
            print_debug(message, PIP_SPECIFIER, version_text, py_exe)

    elif PackagingVersion(version_text) not in PIP_SPECIFIER:
        is_valid = False
        if log_invalid:
            print_warning(message, PIP_SPECIFIER, version_text, py_exe)

    return is_valid
Пример #2
0
    def load_plugins(self):
        import pkgutil
        from rez.backport.importlib import import_module
        type_module_name = 'rezplugins.' + self.type_name
        package = import_module(type_module_name)

        # on import, the `__path__` variable of the imported package is extended
        # to include existing directories on the plugin search path (via
        # extend_path, above). this means that `walk_packages` will walk over all
        # modules on the search path at the same level (.e.g in a
        # 'rezplugins/type_name' sub-directory).
        paths = [package.__path__] if isinstance(package.__path__, basestring) \
            else package.__path__
        for path in paths:
            for loader, modname, ispkg in pkgutil.walk_packages(
                    [path], package.__name__ + '.'):
                if loader is not None:
                    plugin_name = modname.split('.')[-1]
                    if plugin_name.startswith('_'):
                        continue
                    if config.debug("plugins"):
                        print_debug("loading %s plugin at %s: %s..."
                                    % (self.type_name, path, modname))
                    try:
                        # load_module will force reload the module if it's
                        # already loaded, so check for that
                        module = sys.modules.get(modname)
                        if module is None:
                            module = loader.find_module(modname).load_module(modname)
                        if hasattr(module, 'register_plugin') and \
                                hasattr(module.register_plugin, '__call__'):
                            plugin_class = module.register_plugin()
                            if plugin_class != None:
                                self.register_plugin(plugin_name, plugin_class, module)
                            else:
                                if config.debug("plugins"):
                                    print_warning(
                                        "'register_plugin' function at %s: %s did not return a class."
                                        % (path, modname))
                        else:
                            if config.debug("plugins"):
                                print_warning(
                                    "no 'register_plugin' function at %s: %s"
                                    % (path, modname))

                            # delete from sys.modules?

                    except Exception as e:
                        nameish = modname.split('.')[-1]
                        self.failed_plugins[nameish] = str(e)
                        if config.debug("plugins"):
                            import traceback
                            from StringIO import StringIO
                            out = StringIO()
                            traceback.print_exc(file=out)
                            print_debug(out.getvalue())

            # load config
            data, _ = _load_config_from_filepaths([os.path.join(path, "rezconfig")])
            deep_update(self.config_data, data)
Пример #3
0
Файл: git.py Проект: opcg/rez
    def get_changelog(self, previous_revision=None, max_revisions=None):
        prev_commit = None
        if previous_revision is not None:
            try:
                prev_commit = previous_revision["commit"]
            except:
                if self.package.config.debug("package_release"):
                    print_debug("couldn't determine previous commit from: %r" %
                                previous_revision)

        args = ["log"]
        if max_revisions:
            args.extend(["-n", str(max_revisions)])
        if prev_commit:
            # git returns logs to last common ancestor, so even if previous
            # release was from a different branch, this is ok
            try:
                commit_range = "%s..HEAD" % prev_commit
                stdout = self.git("log", commit_range)
            except ReleaseVCSError:
                # Special case where the sha stored in the latest version does not exists due to the
                # git ->github migration where we rewrote the history of the repos
                stdout = self.git("log")
        else:
            stdout = self.git("log")
        return '\n'.join(stdout)
Пример #4
0
    def _cmd(self, *nargs):
        """Convenience function for executing a program such as 'git' etc."""
        cmd_str = ' '.join(map(quote, nargs))

        if self.package.config.debug("package_release"):
            print_debug("Running command: %s" % cmd_str)

        p = Popen(nargs,
                  stdout=subprocess.PIPE,
                  stderr=subprocess.PIPE,
                  cwd=self.pkg_root,
                  text=True)
        out, err = p.communicate()

        if p.returncode:
            print_debug("command stdout:")
            print_debug(out)
            print_debug("command stderr:")
            print_debug(err)
            raise ReleaseVCSError("command failed: %s\n%s" % (cmd_str, err))
        out = out.strip()
        if out:
            return [x.rstrip() for x in out.split('\n')]
        else:
            return []
Пример #5
0
    def load_plugins(self):
        import pkgutil
        from rez.backport.importlib import import_module
        type_module_name = 'rezplugins.' + self.type_name
        package = import_module(type_module_name)

        # on import, the `__path__` variable of the imported package is extended
        # to include existing directories on the plugin search path (via
        # extend_path, above). this means that `walk_packages` will walk over all
        # modules on the search path at the same level (.e.g in a
        # 'rezplugins/type_name' sub-directory).
        paths = [package.__path__] if isinstance(package.__path__, basestring) \
            else package.__path__
        for path in paths:
            for loader, modname, ispkg in pkgutil.walk_packages(
                    [path], package.__name__ + '.'):
                if loader is not None:
                    plugin_name = modname.split('.')[-1]
                    if plugin_name.startswith('_'):
                        continue
                    if config.debug("plugins"):
                        print_debug("loading %s plugin at %s: %s..."
                                    % (self.type_name, path, modname))
                    try:
                        # load_module will force reload the module if it's
                        # already loaded, so check for that
                        module = sys.modules.get(modname)
                        if module is None:
                            module = loader.find_module(modname).load_module(modname)
                        if hasattr(module, 'register_plugin') and \
                                hasattr(module.register_plugin, '__call__'):
                            plugin_class = module.register_plugin()
                            if plugin_class != None:
                                self.register_plugin(plugin_name, plugin_class, module)
                            else:
                                if config.debug("plugins"):
                                    print_warning(
                                        "'register_plugin' function at %s: %s did not return a class."
                                        % (path, modname))
                        else:
                            if config.debug("plugins"):
                                print_warning(
                                    "no 'register_plugin' function at %s: %s"
                                    % (path, modname))

                            # delete from sys.modules?

                    except Exception as e:
                        nameish = modname.split('.')[-1]
                        self.failed_plugins[nameish] = str(e)
                        if config.debug("plugins"):
                            import traceback
                            from StringIO import StringIO
                            out = StringIO()
                            traceback.print_exc(file=out)
                            print_debug(out.getvalue())

            # load config
            data, _ = _load_config_from_filepaths([os.path.join(path, "rezconfig")])
            deep_update(self.config_data, data)
Пример #6
0
    def get_changelog(self, previous_revision=None, max_revisions=None):
        prev_commit = None
        if previous_revision is not None:
            try:
                prev_commit = previous_revision["commit"]
            except:
                if self.package.config.debug("package_release"):
                    print_debug("couldn't determine previous commit from: %r" %
                                previous_revision)

        args = ["log"]
        if max_revisions:
            args.extend(["-l", str(max_revisions)])
        if prev_commit:
            # git behavior is to simply print the log from the last common
            # ancsestor... which is apparently desired. so we'll mimic that

            # however, we want to print in order from most recent to oldest,
            # because:
            #    a) if the log gets truncated, we want to cut off the
            #       oldest commits, not the current one, and
            #    b) this mimics the order they're printed in git
            #    c) this mimics the order they're printed if  you have no
            #       previous_revision, and just do "hg log"
            #    d) if max_revisions is giving, want limiting will only take the
            #       most recent N entries
            commit_range = "reverse(ancestor(%s, .)::.)" % prev_commit
            args.extend(["-r", commit_range])

        stdout = self.hg(*args)
        return '\n'.join(stdout)
Пример #7
0
    def get_changelog(self, previous_revision=None, max_revisions=None):
        prev_commit = None
        if previous_revision is not None:
            try:
                prev_commit = previous_revision["commit"]
            except:
                if self.package.config.debug("package_release"):
                    print_debug("couldn't determine previous commit from: %r"
                                % previous_revision)

        args = ["log"]
        if max_revisions:
            args.extend(["-l", str(max_revisions)])
        if prev_commit:
            # git behavior is to simply print the log from the last common
            # ancsestor... which is apparently desired. so we'll mimic that

            # however, we want to print in order from most recent to oldest,
            # because:
            #    a) if the log gets truncated, we want to cut off the
            #       oldest commits, not the current one, and
            #    b) this mimics the order they're printed in git
            #    c) this mimics the order they're printed if  you have no
            #       previous_revision, and just do "hg log"
            #    d) if max_revisions is giving, want limiting will only take the
            #       most recent N entries
            commit_range = "reverse(ancestor(%s, .)::.)" % prev_commit
            args.extend(["-r", commit_range])

        stdout = self.hg(*args)
        return '\n'.join(stdout)
Пример #8
0
    def get_changelog(self, previous_revision=None, max_revisions=None):
        prev_commit = None
        if previous_revision is not None:
            try:
                prev_commit = previous_revision["commit"]
            except:
                if self.package.config.debug("package_release"):
                    print_debug("couldn't determine previous commit from: %r"
                                % previous_revision)

        args = ["log"]
        if max_revisions:
            args.extend(["-n", str(max_revisions)])
        if prev_commit:
            # git returns logs to last common ancestor, so even if previous
            # release was from a different branch, this is ok
            try:
                commit_range = "%s..HEAD" % prev_commit
                stdout = self.git("log", commit_range)
            except ReleaseVCSError:
                # Special case where the sha stored in the latest version does not exists due to the
                # git ->github migration where we rewrote the history of the repos
                stdout = self.git("log")
        else:
            stdout = self.git("log")
        return '\n'.join(stdout)
Пример #9
0
    def _data(self):
        if not self.schema:
            return None

        data = self._load()
        if config.debug("resources"):
            print_debug("Loaded resource: %s" % str(self))
        return data
Пример #10
0
    def _data(self):
        if not self.schema:
            return None

        data = self._load()
        if config.debug("resources"):
            print_debug("Loaded resource: %s" % str(self))
        return data
Пример #11
0
    def load_module(self, name, package):
        from hashlib import sha1
        from rez.config import config  # avoiding circular import
        from rez.developer_package import DeveloperPackage

        # in rare cases, a @late bound function may get called before the
        # package is built. An example is 'requires' and the other requires-like
        # functions. These need to be evaluated before a build, but it does also
        # make sense to sometimes implement these as late-bound functions. We
        # detect this case here, and load the modules from the original (pre-
        # copied into package payload) location.
        #
        if isinstance(package, DeveloperPackage):
            # load sourcefile from original location
            path = config.package_definition_python_path
            filepath = os.path.join(path, "%s.py" % name)

            if not os.path.exists(filepath):
                return None

            with open(filepath, "rb") as f:
                hash_str = sha1(f.read().strip()).hexdigest()

        else:
            # load sourcefile that's been copied into package install payload
            path = os.path.join(package.base, self.include_modules_subpath)
            pathname = os.path.join(path, "%s.py" % name)
            hashname = os.path.join(path, "%s.sha1" % name)

            if os.path.isfile(pathname) and os.path.isfile(hashname):
                with open(hashname, "r") as f:
                    hash_str = f.readline()
                filepath = pathname

            else:
                # Fallback for backward compat
                pathname = os.path.join(path, "%s-*.py" % name)
                hashnames = glob(pathname)
                if not hashnames:
                    return None

                filepath = hashnames[0]
                hash_str = filepath.rsplit('-', 1)[-1].split('.', 1)[0]
                # End, for details of backward compat,
                # see https://github.com/nerdvegas/rez/issues/934
                # and https://github.com/nerdvegas/rez/pull/935

        module = self.modules.get(hash_str)
        if module is not None:
            return module

        if config.debug("file_loads"):
            print_debug("Loading include sourcefile: %s" % filepath)

        module = py23.load_module_from_file(name, filepath)
        self.modules[hash_str] = module
        return module
Пример #12
0
    def append_if_valid(dir_):
        if os.path.isdir(dir_):
            subdir = os.path.normcase(os.path.join(dir_, pname))
            initfile = os.path.join(subdir, init_py)
            if subdir not in path and os.path.isfile(initfile):
                path.append(subdir)

        elif config.debug("plugins"):
            print_debug("skipped nonexistant rez plugin path: %s" % dir_)
Пример #13
0
def create_release_hooks(names, source_path):
    hooks = []
    for name in names:
        try:
            hook = create_release_hook(name, source_path)
            hooks.append(hook)
        except Exception:
            import traceback
            print_warning("Release hook '%s' is not available." % name)
            print_debug(traceback.format_exc())
    return hooks
Пример #14
0
def _load_file(filepath, format_, update_data_callback):
    load_func = load_functions[format_]

    if config.debug("file_loads"):
        print_debug("Loading file: %s" % filepath)

    with open(filepath) as f:
        result = load_func(f, filepath=filepath)

    if update_data_callback:
        result = update_data_callback(format_, result)
    return result
Пример #15
0
def _load_file(filepath, format_, update_data_callback):
    load_func = load_functions[format_]

    if config.debug("file_loads"):
        print_debug("Loading file: %s" % filepath)

    with open(filepath) as f:
        result = load_func(f, filepath=filepath)

    if update_data_callback:
        result = update_data_callback(format_, result)
    return result
Пример #16
0
    def load_module(self, name, package):
        from rez.config import config  # avoiding circular import
        from rez.developer_package import DeveloperPackage

        # in rare cases, a @late bound function may get called before the
        # package is built. An example is 'requires' and the other requires-like
        # functions. These need to be evaluated before a build, but it does also
        # make sense to sometimes implement these as late-bound functions. We
        # detect this case here, and load the modules from the original (pre-
        # copied into package payload) location.
        #
        if isinstance(package, DeveloperPackage):
            from hashlib import sha1

            # load sourcefile from original location
            path = config.package_definition_python_path
            filepath = os.path.join(path, "%s.py" % name)

            if not os.path.exists(filepath):
                return None

            with open(filepath) as f:
                txt = f.read().strip()

            hash_str = sha1(txt).hexdigest()
        else:
            # load sourcefile that's been copied into package install payload
            path = os.path.join(package.base, self.include_modules_subpath)
            pathname = os.path.join(path, "%s-*.py" % name)

            pathnames = glob(pathname)
            if not pathnames:
                return None

            filepath = pathnames[0]
            hash_str = filepath.rsplit('-', 1)[-1].split('.', 1)[0]

        module = self.modules.get(hash_str)
        if module is not None:
            return module

        if config.debug("file_loads"):
            print_debug("Loading include sourcefile: %s" % filepath)

        with open(filepath) as f:
            module = imp.load_source(name, filepath, f)

        self.modules[hash_str] = module
        return module
Пример #17
0
    def load_module(self, name, package):
        from rez.config import config  # avoiding circular import
        from rez.developer_package import DeveloperPackage

        # in rare cases, a @late bound function may get called before the
        # package is built. An example is 'requires' and the other requires-like
        # functions. These need to be evaluated before a build, but it does also
        # make sense to sometimes implement these as late-bound functions. We
        # detect this case here, and load the modules from the original (pre-
        # copied into package payload) location.
        #
        if isinstance(package, DeveloperPackage):
            from hashlib import sha1

            # load sourcefile from original location
            path = config.package_definition_python_path
            filepath = os.path.join(path, "%s.py" % name)

            if not os.path.exists(filepath):
                return None

            with open(filepath) as f:
                txt = f.read().strip()

            hash_str = sha1(txt).hexdigest()
        else:
            # load sourcefile that's been copied into package install payload
            path = os.path.join(package.base, self.include_modules_subpath)
            pathname = os.path.join(path, "%s-*.py" % name)

            pathnames = glob(pathname)
            if not pathnames:
                return None

            filepath = pathnames[0]
            hash_str = filepath.rsplit('-', 1)[-1].split('.', 1)[0]

        module = self.modules.get(hash_str)
        if module is not None:
            return module

        if config.debug("file_loads"):
            print_debug("Loading include sourcefile: %s" % filepath)

        with open(filepath) as f:
            module = imp.load_source(name, filepath, f)

        self.modules[hash_str] = module
        return module
Пример #18
0
    def test_print(self):
        """Test valid msg and nargs combinations for print_*."""
        for msg in ("Hello", "Hello %s", "Hello %s %s"):
            logging_.print_debug(msg)
            logging_.print_info(msg)
            logging_.print_warning(msg)
            logging_.print_error(msg)
            logging_.print_critical(msg)

            for nargs in ([], ["foo"], ["foo", "bar"]):
                logging_.print_debug(msg, *nargs)
                logging_.print_info(msg, *nargs)
                logging_.print_warning(msg, *nargs)
                logging_.print_error(msg, *nargs)
                logging_.print_critical(msg, *nargs)
Пример #19
0
    def test_print(self):
        """Test valid msg and nargs combinations for print_*."""
        for msg in ("Hello", "Hello %s", "Hello %s %s"):
            logging_.print_debug(msg)
            logging_.print_info(msg)
            logging_.print_warning(msg)
            logging_.print_error(msg)
            logging_.print_critical(msg)

            for nargs in ([], ["foo"], ["foo", "bar"]):
                logging_.print_debug(msg, *nargs)
                logging_.print_info(msg, *nargs)
                logging_.print_warning(msg, *nargs)
                logging_.print_error(msg, *nargs)
                logging_.print_critical(msg, *nargs)
Пример #20
0
Файл: amqp.py Проект: opcg/rez
    def publish_message(self, data):
        if not self.settings.host:
            print_error("Did not publish message, host is not specified")
            return

        routing_key = self.settings.exchange_routing_key
        print("Publishing AMQP message on %s..." % routing_key)

        publish_message(host=self.settings.host,
                        amqp_settings=self.settings,
                        routing_key=routing_key,
                        data=data)

        if config.debug("package_release"):
            print_debug("Published message: %s" % (data))
Пример #21
0
def extend_path(path, name):
    """Extend a package's path.

    Intended use is to place the following code in a package's __init__.py:

        from pkgutil import extend_path
        __path__ = extend_path(__path__, __name__)

    This will add to the package's __path__ all subdirectories of
    directories on sys.path named after the package.  This is useful
    if one wants to distribute different parts of a single logical
    package as multiple directories.

    If the input path is not a list (as is the case for frozen
    packages) it is returned unchanged.  The input path is not
    modified; an extended copy is returned.  Items are only appended
    to the copy at the end.

    It is assumed that 'plugin_path' is a sequence.  Items of 'plugin_path'
    that are not (unicode or 8-bit) strings referring to existing
    directories are ignored.  Unicode items of sys.path that cause
    errors when used as filenames may cause this function to raise an
    exception (in line with os.path.isdir() behavior).
    """
    if not isinstance(path, list):
        # This could happen e.g. when this is called from inside a
        # frozen package.  Return the path unchanged in that case.
        return path

    pname = os.path.join(*name.split('.'))  # Reconstitute as relative path
    # Just in case os.extsep != '.'
    init_py = "__init__" + os.extsep + "py"
    path = path[:]

    for dir in config.plugin_path:
        if not os.path.isdir(dir):
            if config.debug("plugins"):
                print_debug("skipped nonexistant rez plugin path: %s" % dir)
            continue

        subdir = os.path.join(dir, pname)
        # XXX This may still add duplicate entries to path on
        # case-insensitive filesystems
        initfile = os.path.join(subdir, init_py)
        if subdir not in path and os.path.isfile(initfile):
            path.append(subdir)

    return path
Пример #22
0
def extend_path(path, name):
    """Extend a package's path.

    Intended use is to place the following code in a package's __init__.py:

        from pkgutil import extend_path
        __path__ = extend_path(__path__, __name__)

    This will add to the package's __path__ all subdirectories of
    directories on sys.path named after the package.  This is useful
    if one wants to distribute different parts of a single logical
    package as multiple directories.

    If the input path is not a list (as is the case for frozen
    packages) it is returned unchanged.  The input path is not
    modified; an extended copy is returned.  Items are only appended
    to the copy at the end.

    It is assumed that 'plugin_path' is a sequence.  Items of 'plugin_path'
    that are not (unicode or 8-bit) strings referring to existing
    directories are ignored.  Unicode items of sys.path that cause
    errors when used as filenames may cause this function to raise an
    exception (in line with os.path.isdir() behavior).
    """
    if not isinstance(path, list):
        # This could happen e.g. when this is called from inside a
        # frozen package.  Return the path unchanged in that case.
        return path

    pname = os.path.join(*name.split('.'))  # Reconstitute as relative path
    # Just in case os.extsep != '.'
    init_py = "__init__" + os.extsep + "py"
    path = path[:]

    for dir in config.plugin_path:
        if not os.path.isdir(dir):
            if config.debug("plugins"):
                print_debug("skipped nonexistant rez plugin path: %s" % dir)
            continue

        subdir = os.path.join(dir, pname)
        # XXX This may still add duplicate entries to path on
        # case-insensitive filesystems
        initfile = os.path.join(subdir, init_py)
        if subdir not in path and os.path.isfile(initfile):
            path.append(subdir)

    return path
Пример #23
0
    def publish_message(self, data):
        if not self.settings.host:
            print_error("Did not publish message, host is not specified")
            return

        try:
            conn = Connection(host=self.settings.host,
                              port=self.settings.port,
                              userid=self.settings.userid,
                              password=self.settings.password,
                              connect_timeout=self.settings.connect_timeout)
        except socket.error as e:
            print_error("Cannot connect to the message broker: %s" % (e))
            return

        channel = conn.channel()

        # Declare the exchange
        try:
            channel.exchange_declare(
                self.settings.exchange_name,
                self.settings.exchange_type,
                durable=self.settings.exchange_durable,
                auto_delete=self.settings.exchange_auto_delete)
        except Exception as e:
            print_error("Failed to declare an exchange: %s" % (e))
            return

        # build the message
        msg = basic_message.Message(
            body=json.dumps(data),
            delivery_mode=self.settings.message_delivery_mode,
            content_type="application/json",
            content_encoding="utf-8")

        routing_key = self.settings.exchange_routing_key
        print "Publishing AMQP message on %s..." % routing_key

        # publish the message
        try:
            channel.basic_publish(msg, self.settings.exchange_name,
                                  routing_key)
        except Exception as e:
            print_error("Failed to publish message: %s" % (e))
            return

        if config.debug("package_release"):
            print_debug("Published message: %s" % (data))
Пример #24
0
    def _cmd(self, *nargs):
        """Convenience function for executing a program such as 'git' etc."""
        cmd_str = ' '.join(nargs)
        if self.package.config.debug("package_release"):
            print_debug("Running command: %s" % cmd_str)

        p = subprocess.Popen(nargs, stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE, cwd=self.pkg_root)
        out, err = p.communicate()
        if p.returncode:
            raise ReleaseVCSError("command failed: %s\n%s" % (cmd_str, err))
        out = out.strip()
        if out:
            return [x.rstrip() for x in out.split('\n')]
        else:
            return []
Пример #25
0
    def publish_message(self, data):
        if not self.settings.host:
            print_error("Did not publish message, host is not specified")
            return

        try:
            conn = Connection(host=self.settings.host,
                              port=self.settings.port,
                              userid=self.settings.userid,
                              password=self.settings.password,
                              connect_timeout=self.settings.connect_timeout)
        except socket.error as e:
            print_error("Cannot connect to the message broker: %s" % (e))
            return

        channel = conn.channel()

        # Declare the exchange
        try:
            channel.exchange_declare(
                self.settings.exchange_name,
                self.settings.exchange_type,
                durable=self.settings.exchange_durable,
                auto_delete=self.settings.exchange_auto_delete)
        except Exception as e:
            print_error("Failed to declare an exchange: %s" % (e))
            return

        # build the message
        msg = basic_message.Message(
            body=json.dumps(data),
            delivery_mode=self.settings.message_delivery_mode,
            content_type="application/json",
            content_encoding="utf-8")

        routing_key = self.settings.exchange_routing_key
        print "Publishing AMQP message on %s..." % routing_key

        # publish the message
        try:
            channel.basic_publish(msg, self.settings.exchange_name, routing_key)
        except Exception as e:
            print_error("Failed to publish message: %s" % (e))
            return

        if config.debug("package_release"):
            print_debug("Published message: %s" % (data))
Пример #26
0
    def _release(self, commands, errors=None):
        for conf in commands:
            if self.settings.print_commands or config.debug("package_release"):
                from subprocess import list2cmdline
                toks = [conf["command"]] + conf.get("args", [])
                msg = "running command: %s" % list2cmdline(toks)
                if self.settings.print_commands:
                    print msg
                else:
                    print_debug(msg)

            if not self.execute_command(cmd_name=conf.get("command"),
                                        cmd_arguments=conf.get("args"),
                                        user=conf.get("user"),
                                        errors=errors):
                if self.settings.stop_on_error:
                    return
Пример #27
0
    def post_release(self, user, install_path, variants, **kwargs):
        # note that the package we use here is the *installed* package, not the
        # developer package (self.package). Otherwise, attributes such as 'root'
        # will be None
        errors = []
        if variants:
            package = variants[0].parent
        else:
            package = self.package

        self._execute_commands(self.settings.post_release_commands,
                               install_path=install_path,
                               package=package,
                               errors=errors)
        if errors:
            print_debug("The following post-release commands failed:\n"
                        + '\n\n'.join(errors))
Пример #28
0
def load_plugin_cmd():
    """Load subcommand from command type plugin

    The command type plugin module should have attribute `command_behavior`,
    and the value must be a dict if provided. For example:

        # in your command plugin module
        command_behavior = {
            "hidden": False,   # (bool): default False
            "arg_mode": None,  #  (str): "passthrough", "grouped", default None
        }

    If the attribute not present, default behavior will be given.

    """
    from rez.config import config
    from rez.utils.logging_ import print_debug
    from rez.plugin_managers import plugin_manager

    ext_plugins = dict()

    for plugin_name in plugin_manager.get_plugins("command"):
        module = plugin_manager.get_plugin_module("command", plugin_name)

        behavior = getattr(module, "command_behavior", None)
        if behavior is None:
            behavior = dict()

            if config.debug("plugins"):
                print_debug("Attribute 'command_behavior' not found in plugin "
                            "module %s, registering with default behavior." %
                            module.__name__)
        try:
            data = behavior.copy()
            data.update({"module_name": module.__name__})
            ext_plugins[plugin_name] = data

        except Exception:
            if config.debug("plugins"):
                import traceback
                from rez.vendor.six.six import StringIO
                out = StringIO()
                traceback.print_exc(file=out)
                print_debug(out.getvalue())

    return ext_plugins
Пример #29
0
    def post_release(self, user, install_path, variants, **kwargs):
        # note that the package we use here is the *installed* package, not the
        # developer package (self.package). Otherwise, attributes such as 'root'
        # will be None
        errors = []
        if variants:
            package = variants[0].parent
        else:
            package = self.package

        self._execute_commands(self.settings.post_release_commands,
                               install_path=install_path,
                               package=package,
                               errors=errors)
        if errors:
            print_debug("The following post-release commands failed:\n" +
                        '\n\n'.join(errors))
Пример #30
0
    def get_changelog(self, previous_revision=None):
        prev_commit = None
        if previous_revision is not None:
            try:
                prev_commit = previous_revision["commit"]
            except:
                if self.package.config.debug("package_release"):
                    print_debug("couldn't determine previous commit from: %r"
                                % previous_revision)

        if prev_commit:
            # git returns logs to last common ancestor, so even if previous
            # release was from a different branch, this is ok
            commit_range = "%s..HEAD" % prev_commit
            stdout = self.git("log", commit_range)
        else:
            stdout = self.git("log")
        return '\n'.join(stdout)
Пример #31
0
    def get_changelog(self, previous_revision=None):
        prev_commit = None
        if previous_revision is not None:
            try:
                prev_commit = previous_revision["commit"]
            except:
                if self.package.config.debug("package_release"):
                    print_debug("couldn't determine previous commit from: %r" %
                                previous_revision)

        if prev_commit:
            # git behavior is to simply print the log from the last common
            # ancsestor... which is apparently desired. so we'll mimic that
            commit_range = "ancestor(%s, .)::." % prev_commit
            stdout = self.hg("log", "-r", commit_range)
        else:
            stdout = self.hg("log")
        return '\n'.join(stdout)
Пример #32
0
Файл: git.py Проект: sonictk/rez
    def get_changelog(self, previous_revision=None):
        prev_commit = None
        if previous_revision is not None:
            try:
                prev_commit = previous_revision["commit"]
            except:
                if self.package.config.debug("package_release"):
                    print_debug("couldn't determine previous commit from: %r" % previous_revision)

        if prev_commit:
            # git returns logs to last common ancestor, so even if previous
            # release was from a different branch, this is ok
            commit_range = "%s..HEAD" % prev_commit
            stdout = self.git("log", commit_range)
        else:
            stdout = self.git("log")

        return "\n".join(stdout)
Пример #33
0
    def get_changelog(self, previous_revision=None):
        prev_commit = None
        if previous_revision is not None:
            try:
                prev_commit = previous_revision["commit"]
            except:
                if self.package.config.debug("package_release"):
                    print_debug("couldn't determine previous commit from: %r"
                                % previous_revision)

        if prev_commit:
            # git behavior is to simply print the log from the last common
            # ancsestor... which is apparently desired. so we'll mimic that
            commit_range = "ancestor(%s, .)::." % prev_commit
            stdout = self.hg("log", "-r", commit_range)
        else:
            stdout = self.hg("log")
        return '\n'.join(stdout)
Пример #34
0
    def _execute_commands(self, commands, install_path, package, errors=None):
        release_dict = dict(path=install_path)
        formatter = scoped_formatter(system=system,
                                     release=release_dict,
                                     package=package)

        for conf in commands:
            program = conf["command"]

            env_ = None
            env = conf.get("env")
            if env:
                env_ = os.environ.copy()
                env_.update(env)

            args = conf.get("args", [])
            args = [formatter.format(x) for x in args]
            args = [expandvars(x, environ=env_) for x in args]

            if self.settings.print_commands or config.debug("package_release"):
                from subprocess import list2cmdline
                toks = [program] + args

                msgs = []
                msgs.append("running command: %s" % list2cmdline(toks))
                if env:
                    for key, value in env.iteritems():
                        msgs.append("    with: %s=%s" % (key, value))

                if self.settings.print_commands:
                    print '\n'.join(msgs)
                else:
                    for msg in msgs:
                        print_debug(msg)

            if not self.execute_command(cmd_name=program,
                                        cmd_arguments=args,
                                        user=conf.get("user"),
                                        errors=errors,
                                        env=env_):
                if self.settings.stop_on_error:
                    return
Пример #35
0
    def _execute_commands(self, commands, install_path, package, errors=None):
        release_dict = dict(path=install_path)
        formatter = scoped_formatter(system=system,
                                     release=release_dict,
                                     package=package)

        for conf in commands:
            program = conf["command"]

            env_ = None
            env = conf.get("env")
            if env:
                env_ = os.environ.copy()
                env_.update(env)

            args = conf.get("args", [])
            args = [formatter.format(x) for x in args]
            args = [expandvars(x, environ=env_) for x in args]

            if self.settings.print_commands or config.debug("package_release"):
                from subprocess import list2cmdline
                toks = [program] + args

                msgs = []
                msgs.append("running command: %s" % list2cmdline(toks))
                if env:
                    for key, value in env.iteritems():
                        msgs.append("    with: %s=%s" % (key, value))

                if self.settings.print_commands:
                    print '\n'.join(msgs)
                else:
                    for msg in msgs:
                        print_debug(msg)

            if not self.execute_command(cmd_name=program,
                                        cmd_arguments=args,
                                        user=conf.get("user"),
                                        errors=errors,
                                        env=env_):
                if self.settings.stop_on_error:
                    return
Пример #36
0
    def get_changelog(self, previous_revision=None, max_revisions=None):
        prev_commit = None
        if previous_revision is not None:
            try:
                prev_commit = previous_revision["commit"]
            except:
                if self.package.config.debug("package_release"):
                    print_debug("couldn't determine previous commit from: %r"
                                % previous_revision)

        args = ["log"]
        if max_revisions:
            args.extend(["-n", str(max_revisions)])
        if prev_commit:
            # git returns logs to last common ancestor, so even if previous
            # release was from a different branch, this is ok
            commit_range = "%s..HEAD" % prev_commit
            args.append(commit_range)
        stdout = self.git(*args)

        return '\n'.join(stdout)
Пример #37
0
    def get_changelog(self, previous_revision=None, max_revisions=None):
        prev_commit = None
        if previous_revision is not None:
            try:
                prev_commit = previous_revision["commit"]
            except:
                if self.package.config.debug("package_release"):
                    print_debug("couldn't determine previous commit from: %r" %
                                previous_revision)

        args = ["log"]
        if max_revisions:
            args.extend(["-n", str(max_revisions)])
        if prev_commit:
            # git returns logs to last common ancestor, so even if previous
            # release was from a different branch, this is ok
            commit_range = "%s..HEAD" % prev_commit
            args.append(commit_range)
        stdout = self.git(*args)

        return '\n'.join(stdout)
Пример #38
0
    def _execute_commands(self,
                          commands,
                          install_path,
                          package,
                          errors=None,
                          variants=None):
        release_dict = dict(path=install_path)
        variant_infos = []
        if variants:
            for variant in variants:
                if isinstance(variant, (int, long)):
                    variant_infos.append(variant)
                else:
                    package = variant.parent
                    var_dict = dict(variant.resource.variables)
                    # using '%s' will preserve potential str/unicode nature
                    var_dict['variant_requires'] = [
                        '%s' % x for x in variant.resource.variant_requires
                    ]
                    variant_infos.append(var_dict)
        formatter = scoped_formatter(system=system,
                                     release=release_dict,
                                     package=package,
                                     variants=variant_infos,
                                     num_variants=len(variant_infos))

        for conf in commands:
            program = conf["command"]

            env_ = None
            env = conf.get("env")
            if env:
                env_ = os.environ.copy()
                env_.update(env)

            # If we have, ie, a list, and format_pretty is True, it will be printed
            # as "1 2 3" instead of "[1, 2, 3]"
            formatter.__dict__['format_pretty'] = conf.get("pretty_args", True)

            args = conf.get("args", [])
            args = [formatter.format(x) for x in args]
            args = [expandvars(x, environ=env_) for x in args]

            if self.settings.print_commands or config.debug("package_release"):
                from subprocess import list2cmdline
                toks = [program] + args

                msgs = []
                msgs.append("running command: %s" % list2cmdline(toks))
                if env:
                    for key, value in env.iteritems():
                        msgs.append("    with: %s=%s" % (key, value))

                if self.settings.print_commands:
                    print('\n'.join(msgs))
                else:
                    for msg in msgs:
                        print_debug(msg)

            if not self.execute_command(cmd_name=program,
                                        cmd_arguments=args,
                                        user=conf.get("user"),
                                        errors=errors,
                                        env=env_):
                if self.settings.stop_on_error:
                    return
Пример #39
0
def _log(msg):
    if _verbose:
        print_debug(msg)
Пример #40
0
def log(msg):
    if config.debug("bind_modules"):
        print_debug(msg)
Пример #41
0
def _log(msg):
    if _verbose:
        print_debug(msg)
Пример #42
0
def find_pip_from_context(python_version, pip_version=None):
    """Find pip from rez context.

    Args:
        python_version (str or `Version`): Python version to use
        pip_version (str or `Version`): Version of pip to use, or latest.

    Returns:
        3-tuple:
        - str: Python executable or None if we fell back to system pip.
        - str: Pip version or None if we fell back to system pip.
        - `ResolvedContext`: Context containing pip, or None if we fell back
          to system pip.
    """
    target = "python"
    package_request = []

    if python_version:
        ver = Version(str(python_version))
        python_major_minor_ver = ver.trim(2)
    else:
        # use latest major.minor
        package = get_latest_package("python")
        if package:
            python_major_minor_ver = package.version.trim(2)
        else:
            raise BuildError("Found no python package.")

    python_package = "python-%s" % str(python_major_minor_ver)

    package_request.append(python_package)

    if pip_version:
        target = "pip"
        if pip_version == "latest":
            package_request.append("pip")
        else:
            package_request.append("pip-%s" % str(pip_version))

    print_info("Trying to use pip from %s package", target)

    try:
        context = ResolvedContext(package_request)
    except (PackageFamilyNotFoundError, PackageNotFoundError):
        print_debug("No rez package called %s found", target)
        return None, None, None

    py_exe_name = "python"
    if platform_.name != "windows":
        # Python < 2 on Windows doesn't have versionned executable.
        py_exe_name += str(python_major_minor_ver.trim(1))

    py_exe = context.which(py_exe_name)

    proc = context.execute_command(
        # -E and -s are used to isolate the environment as much as possible.
        # See python --help for more details. We absolutely don't want to get
        # pip from the user home.
        [
            py_exe, "-E", "-s", "-c",
            "import pip, sys; sys.stdout.write(pip.__version__)"
        ],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        text=True)
    out, err = proc.communicate()
    if proc.returncode:
        print_debug("Failed to get pip from package %s", target)
        print_debug(out)
        print_debug(err)
        return None, None, None

    pip_version = out.strip()

    variant = context.get_resolved_package(target)
    package = variant.parent
    print_info("Found pip-%s inside %s. Will use it with %s", pip_version,
               package.uri, py_exe)

    return py_exe, pip_version, context
Пример #43
0
    def _execute_commands(self, commands, install_path, package, errors=None,
                          variants=None):
        release_dict = dict(path=install_path)
        variant_infos = []
        if variants:
            for variant in variants:
                if isinstance(variant, (int, long)):
                    variant_infos.append(variant)
                else:
                    package = variant.parent
                    var_dict = dict(variant.resource.variables)
                    # using '%s' will preserve potential str/unicode nature
                    var_dict['variant_requires'] = ['%s' % x
                                                    for x in variant.resource.variant_requires]
                    variant_infos.append(var_dict)
        formatter = scoped_formatter(system=system,
                                     release=release_dict,
                                     package=package,
                                     variants=variant_infos,
                                     num_variants=len(variant_infos))

        for conf in commands:
            program = conf["command"]

            env_ = None
            env = conf.get("env")
            if env:
                env_ = os.environ.copy()
                env_.update(env)

            # If we have, ie, a list, and format_pretty is True, it will be printed
            # as "1 2 3" instead of "[1, 2, 3]"
            formatter.__dict__['format_pretty'] = conf.get(
                "pretty_args", True)

            args = conf.get("args", [])
            args = [formatter.format(x) for x in args]
            args = [expandvars(x, environ=env_) for x in args]

            if self.settings.print_commands or config.debug("package_release"):
                from subprocess import list2cmdline
                toks = [program] + args

                msgs = []
                msgs.append("running command: %s" % list2cmdline(toks))
                if env:
                    for key, value in env.iteritems():
                        msgs.append("    with: %s=%s" % (key, value))

                if self.settings.print_commands:
                    print '\n'.join(msgs)
                else:
                    for msg in msgs:
                        print_debug(msg)

            if not self.execute_command(cmd_name=program,
                                        cmd_arguments=args,
                                        user=conf.get("user"),
                                        errors=errors,
                                        env=env_):
                if self.settings.stop_on_error:
                    return
Пример #44
0
    def load_plugins(self):
        import pkgutil
        from rez.backport.importlib import import_module
        type_module_name = 'rezplugins.' + self.type_name
        package = import_module(type_module_name)

        # on import, the `__path__` variable of the imported package is extended
        # to include existing directories on the plugin search path (via
        # extend_path, above). this means that `walk_packages` will walk over all
        # modules on the search path at the same level (.e.g in a
        # 'rezplugins/type_name' sub-directory).
        paths = [package.__path__] if isinstance(package.__path__, basestring) \
            else package.__path__

        # reverse plugin path order, so that custom plugins have a chance to
        # be found before the builtin plugins (from /rezplugins).
        paths = reversed(paths)

        for path in paths:
            if config.debug("plugins"):
                print_debug("searching plugin path %s...", path)

            for importer, modname, ispkg in pkgutil.iter_modules(
                [path], package.__name__ + '.'):

                if importer is None:
                    continue

                plugin_name = modname.split('.')[-1]
                if plugin_name.startswith('_') or plugin_name == 'rezconfig':
                    continue

                if plugin_name in self.plugin_modules:
                    # same named plugins will have identical module name,
                    # which will just reuse previous imported module from
                    # `sys.modules` below. skipping the rest of the process
                    # for good.
                    if config.debug("plugins"):
                        print_warning(
                            "skipped same named %s plugin at %s: %s" %
                            (self.type_name, path, modname))
                    continue

                if config.debug("plugins"):
                    print_debug("loading %s plugin at %s: %s..." %
                                (self.type_name, path, modname))
                try:
                    # nerdvegas/rez#218
                    # load_module will force reload the module if it's
                    # already loaded, so check for that
                    plugin_module = sys.modules.get(modname)
                    if plugin_module is None:
                        loader = importer.find_module(modname)
                        plugin_module = loader.load_module(modname)

                    elif os.path.dirname(plugin_module.__file__) != path:
                        if config.debug("plugins"):
                            # this should not happen but if it does, tell why.
                            print_warning(
                                "plugin module %s is not loaded from current "
                                "load path but reused from previous imported "
                                "path: %s" % (modname, plugin_module.__file__))

                    if (hasattr(plugin_module, "register_plugin")
                            and callable(plugin_module.register_plugin)):

                        plugin_class = plugin_module.register_plugin()
                        if plugin_class is not None:
                            self.register_plugin(plugin_name, plugin_class,
                                                 plugin_module)
                        else:
                            if config.debug("plugins"):
                                print_warning(
                                    "'register_plugin' function at %s: %s did "
                                    "not return a class." % (path, modname))
                    else:
                        if config.debug("plugins"):
                            print_warning(
                                "no 'register_plugin' function at %s: %s" %
                                (path, modname))

                        # delete from sys.modules?

                except Exception as e:
                    nameish = modname.split('.')[-1]
                    self.failed_plugins[nameish] = str(e)
                    if config.debug("plugins"):
                        import traceback
                        from rez.vendor.six.six import StringIO
                        out = StringIO()
                        traceback.print_exc(file=out)
                        print_debug(out.getvalue())

            # load config
            data, _ = _load_config_from_filepaths(
                [os.path.join(path, "rezconfig")])
            deep_update(self.config_data, data)
Пример #45
0
def log(msg):
    if config.debug("bind_modules"):
        print_debug(msg)
Пример #46
0
def convert_old_commands(commands, annotate=True):
    """Converts old-style package commands into equivalent Rex code."""
    from rez.config import config
    from rez.utils.logging_ import print_debug

    def _repl(s):
        return s.replace('\\"', '"')

    def _encode(s):
        # this replaces all occurrances of '\"' with '"', *except* for those
        # occurrances of '\"' that are within double quotes, which themselves
        # are not escaped. In other words, the string:
        # 'hey "there \"you\" " \"dude\" '
        # ..will convert to:
        # 'hey "there \"you\" " "dude" '
        s_new = ''
        prev_i = 0

        for m in within_unescaped_quotes_regex.finditer(s):
            s_ = s[prev_i:m.start()]
            s_new += _repl(s_)

            s_new += s[m.start():m.end()]
            prev_i = m.end()

        s_ = s[prev_i:]
        s_new += _repl(s_)
        return repr(s_new)

    loc = []

    for cmd in commands:
        if annotate:
            txt = "OLD COMMAND: %s" % cmd
            line = "comment(%s)" % _encode(txt)
            loc.append(line)

        cmd = convert_old_command_expansions(cmd)
        toks = cmd.strip().split()

        try:
            if toks[0] == "export":
                var, value = cmd.split(' ', 1)[1].split('=', 1)
                for bookend in ('"', "'"):
                    if value.startswith(bookend) and value.endswith(bookend):
                        value = value[1:-1]
                        break

                # As the only old-style commands were Linux/Bash based,
                # we assume using the default separator ":" is ok - we don't
                # need to use os.pathsep as we don't expected to see a
                # Windows path here.
                separator = config.env_var_separators.get(var, ":")

                # This is a special case.  We don't want to include "';'" in
                # our env var separators map as it's not really the correct
                # behaviour/something we want to promote.  It's included here for
                # backwards compatibility only, and to not propogate elsewhere.
                if var == "CMAKE_MODULE_PATH":
                    value = value.replace("'%s'" % separator, separator)
                    value = value.replace('"%s"' % separator, separator)
                    value = value.replace(":", separator)

                parts = value.split(separator)
                parts = [x for x in parts if x]
                if len(parts) > 1:
                    idx = None
                    var1 = "$%s" % var
                    var2 = "${%s}" % var
                    if var1 in parts:
                        idx = parts.index(var1)
                    elif var2 in parts:
                        idx = parts.index(var2)
                    if idx in (0, len(parts) - 1):
                        func = "appendenv" if idx == 0 else "prependenv"
                        parts = parts[1:] if idx == 0 else parts[:-1]
                        val = separator.join(parts)
                        loc.append("%s('%s', %s)" % (func, var, _encode(val)))
                        continue

                loc.append("setenv('%s', %s)" % (var, _encode(value)))
            elif toks[0].startswith('#'):
                loc.append("comment(%s)" % _encode(' '.join(toks[1:])))
            elif toks[0] == "alias":
                match = re.search("alias (?P<key>.*?)=(?P<value>.*)", cmd)
                key = match.groupdict()['key'].strip()
                value = match.groupdict()['value'].strip()
                if (value.startswith('"') and value.endswith('"')) or \
                        (value.startswith("'") and value.endswith("'")):
                    value = value[1:-1]
                loc.append("alias('%s', %s)" % (key, _encode(value)))
            else:
                # assume we can execute this as a straight command
                loc.append("command(%s)" % _encode(cmd))
        except:
            # if anything goes wrong, just fall back to bash command
            loc.append("command(%s)" % _encode(cmd))

    rex_code = '\n'.join(loc)
    if config.debug("old_commands"):
        br = '-' * 80
        msg = textwrap.dedent("""
            %s
            OLD COMMANDS:
            %s

            NEW COMMANDS:
            %s
            %s
            """) % (br, '\n'.join(commands), rex_code, br)
        print_debug(msg)
    return rex_code
Пример #47
0
def convert_old_commands(commands, annotate=True):
    """Converts old-style package commands into equivalent Rex code."""
    from rez.config import config
    from rez.utils.logging_ import print_debug

    def _repl(s):
        return s.replace('\\"', '"')

    def _encode(s):
        # this replaces all occurrances of '\"' with '"', *except* for those
        # occurrances of '\"' that are within double quotes, which themselves
        # are not escaped. In other words, the string:
        # 'hey "there \"you\" " \"dude\" '
        # ..will convert to:
        # 'hey "there \"you\" " "dude" '
        s_new = ''
        prev_i = 0

        for m in within_unescaped_quotes_regex.finditer(s):
            s_ = s[prev_i:m.start()]
            s_new += _repl(s_)

            s_new += s[m.start():m.end()]
            prev_i = m.end()

        s_ = s[prev_i:]
        s_new += _repl(s_)
        return repr(s_new)

    loc = []

    for cmd in commands:
        if annotate:
            txt = "OLD COMMAND: %s" % cmd
            line = "comment(%s)" % _encode(txt)
            loc.append(line)

        cmd = convert_old_command_expansions(cmd)
        toks = cmd.strip().split()

        if toks[0] == "export":
            var, value = cmd.split(' ', 1)[1].split('=', 1)
            for bookend in ('"', "'"):
                if value.startswith(bookend) and value.endswith(bookend):
                    value = value[1:-1]
                    break

            # As the only old-style commands were Linux/Bash based,
            # we assume using the default separator ":" is ok - we don't
            # need to use os.pathsep as we don't expected to see a
            # Windows path here.
            separator = config.env_var_separators.get(var, ":")

            # This is a special case.  We don't want to include "';'" in
            # our env var separators map as it's not really the correct
            # behaviour/something we want to promote.  It's included here for
            # backwards compatibility only, and to not propogate elsewhere.
            if var == "CMAKE_MODULE_PATH":
                value = value.replace("'%s'" % separator, separator)
                value = value.replace('"%s"' % separator, separator)
                value = value.replace(":", separator)

            parts = value.split(separator)
            parts = [x for x in parts if x]
            if len(parts) > 1:
                idx = None
                var1 = "$%s" % var
                var2 = "${%s}" % var
                if var1 in parts:
                    idx = parts.index(var1)
                elif var2 in parts:
                    idx = parts.index(var2)
                if idx in (0, len(parts) - 1):
                    func = "appendenv" if idx == 0 else "prependenv"
                    parts = parts[1:] if idx == 0 else parts[:-1]
                    val = separator.join(parts)
                    loc.append("%s('%s', %s)" % (func, var, _encode(val)))
                    continue

            loc.append("setenv('%s', %s)" % (var, _encode(value)))
        elif toks[0].startswith('#'):
            loc.append("comment(%s)" % _encode(' '.join(toks[1:])))
        elif toks[0] == "alias":
            match = re.search("alias (?P<key>.*?)=(?P<value>.*)", cmd)
            key = match.groupdict()['key'].strip()
            value = match.groupdict()['value'].strip()
            if (value.startswith('"') and value.endswith('"')) or \
                    (value.startswith("'") and value.endswith("'")):
                value = value[1:-1]
            loc.append("alias('%s', %s)" % (key, _encode(value)))
        else:
            # assume we can execute this as a straight command
            loc.append("command(%s)" % _encode(cmd))

    rex_code = '\n'.join(loc)
    if config.debug("old_commands"):
        br = '-' * 80
        msg = textwrap.dedent(
            """
            %s
            OLD COMMANDS:
            %s

            NEW COMMANDS:
            %s
            %s
            """) % (br, '\n'.join(commands), rex_code, br)
        print_debug(msg)
    return rex_code