コード例 #1
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 []
コード例 #2
0
    def _physical_cores_from_wmic(self):
        # windows
        import subprocess
        try:
            p = Popen('wmic cpu get NumberOfCores /value'.split(),
                      stdout=subprocess.PIPE,
                      stderr=subprocess.PIPE,
                      text=True)
        except (OSError, IOError):
            return None

        stdout, stderr = p.communicate()
        if p.returncode:
            return None

        # a Windows machine with 1 installed CPU will return "NumberOfCores=N" where N is
        # the number of physical cores on that CPU chip. If more than one CPU is installed
        # there will be one "NumberOfCores=N" line listed per actual CPU, so the sum of all
        # N is the number of physical cores in the machine: this will be exactly one half the
        # number of logical cores (ie from multiprocessing.cpu_count) if HyperThreading is
        # enabled on the CPU(s)
        result = re.findall(r'NumberOfCores=(\d+)', stdout.strip())

        if not result:
            # don't know what's wrong... should get back a result like:
            # NumberOfCores=2
            return None

        return sum(map(int, result))
コード例 #3
0
def exec_python(attr, src, executable="python"):
    """Runs a python subproc to calculate a package attribute.

    Args:
        attr (str): Name of package attribute being created.
        src (list of str): Python code to execute, will be converted into
            semicolon-delimited single line of code.

    Returns:
        str: Output of python process.
    """
    import subprocess

    if isinstance(src, basestring):
        src = [src]

    p = Popen([executable, "-c", "; ".join(src)],
              stdout=subprocess.PIPE,
              stderr=subprocess.PIPE,
              text=True)
    out, err = p.communicate()

    if p.returncode:
        from rez.exceptions import InvalidPackageError
        raise InvalidPackageError(
            "Error determining package attribute '%s':\n%s" % (attr, err))

    return out.strip()
コード例 #4
0
ファイル: sh.py プロジェクト: wwfxuk/rez
    def get_syspaths(cls):
        if cls.syspaths is not None:
            return cls.syspaths

        if config.standard_system_paths:
            cls.syspaths = config.standard_system_paths
            return cls.syspaths

        # detect system paths using registry
        cmd = "cmd=`which %s`; unset PATH; $cmd %s %s 'echo __PATHS_ $PATH'" \
              % (cls.name(), cls.norc_arg, cls.command_arg)
        p = Popen(cmd, stdout=subprocess.PIPE,
                  stderr=subprocess.PIPE, shell=True, text=True)
        out_, err_ = p.communicate()
        if p.returncode:
            paths = []
        else:
            lines = out_.split('\n')
            line = [x for x in lines if "__PATHS_" in x.split()][0]
            paths = line.strip().split()[-1].split(os.pathsep)

        for path in os.defpath.split(os.path.pathsep):
            if path not in paths:
                paths.append(path)
        cls.syspaths = [x for x in paths if x]
        return cls.syspaths
コード例 #5
0
def find_site_python(module_name, paths=None):
    """Find the rez native python package that contains the given module.

    This function is used by python 'native' rez installers to find the native
    rez python package that represents the python installation that this module
    is installed into.

    Note:
        This function is dependent on the behavior found in the python '_native'
        package found in the 'rez-recipes' repository. Specifically, it expects
        to find a python package with a '_site_paths' list attribute listing
        the site directories associated with the python installation.

    Args:
        module_name (str): Target python module.
        paths (list of str, optional): paths to search for packages,
            defaults to `config.packages_path`.

    Returns:
        `Package`: Native python package containing the named module.
    """
    from rez.packages import iter_packages
    import subprocess
    import ast
    import os

    py_cmd = 'import {x}; print({x}.__path__)'.format(x=module_name)

    p = Popen(["python", "-c", py_cmd],
              stdout=subprocess.PIPE,
              stderr=subprocess.PIPE,
              text=True)
    out, err = p.communicate()

    if p.returncode:
        raise InvalidPackageError(
            "Failed to find installed python module '%s':\n%s" %
            (module_name, err))

    module_paths = ast.literal_eval(out.strip())

    def issubdir(path, parent_path):
        return path.startswith(parent_path + os.sep)

    for package in iter_packages("python", paths=paths):
        if not hasattr(package, "_site_paths"):
            continue

        contained = True

        for module_path in module_paths:
            if not any(issubdir(module_path, x) for x in package._site_paths):
                contained = False

        if contained:
            return package

    raise InvalidPackageError(
        "Failed to find python installation containing the module '%s'. Has "
        "python been installed as a rez package?" % module_name)
コード例 #6
0
    def _physical_cores_from_lscpu(self):
        import subprocess
        try:
            p = Popen(['lscpu'],
                      stdout=subprocess.PIPE,
                      stderr=subprocess.PIPE,
                      text=True)
        except (OSError, IOError):
            return None

        stdout, stderr = p.communicate()
        if p.returncode:
            return None

        data = self._parse_colon_table_to_dict(stdout)

        # lscpu gives output like this:
        #
        # CPU(s):                24
        # On-line CPU(s) list:   0-23
        # Thread(s) per core:    2
        # Core(s) per socket:    6
        # Socket(s):             2

        # we want to take sockets * cores, and ignore threads...

        # some versions of lscpu format the sockets line differently...
        sockets = data.get('Socket(s)', data.get('CPU socket(s)'))
        if not sockets:
            return None
        cores = data.get('Core(s) per socket')
        if not cores:
            return None
        return int(sockets) * int(cores)
コード例 #7
0
 def _open_url(cls, url):
     if config.browser:
         cmd = [config.browser, url]
         if not config.quiet:
             print("running command: %s" % " ".join(cmd))
         p = Popen(cmd)
         p.communicate()
     else:
         if not config.quiet:
             print("opening URL in browser: %s" % url)
         webbrowser.open_new(url)
コード例 #8
0
def _cmd(context, command):
    cmd_str = ' '.join(quote(x) for x in command)
    _log("running: %s" % cmd_str)

    if context is None:
        p = Popen(command)
    else:
        p = context.execute_shell(command=command, block=False)

    with p:
        p.wait()

    if p.returncode:
        raise BuildError("Failed to download source with pip: %s" % cmd_str)
コード例 #9
0
def exec_command(attr, cmd):
    """Runs a subproc to calculate a package attribute.
    """
    import subprocess

    p = Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
    out, err = p.communicate()

    if p.returncode:
        from rez.exceptions import InvalidPackageError
        raise InvalidPackageError(
            "Error determining package attribute '%s':\n%s" % (attr, err))

    return out.strip(), err.strip()
コード例 #10
0
def _run_command(args):
    cmd_str = ' '.join(quote(x) for x in args)
    log("running: %s" % cmd_str)

    # https://github.com/nerdvegas/rez/pull/659
    use_shell = ("Windows" in platform.system())

    p = Popen(args,
              stdout=subprocess.PIPE,
              stderr=subprocess.PIPE,
              shell=use_shell,
              text=True)

    stdout, stderr = p.communicate()
    return stdout, stderr, p.returncode
コード例 #11
0
    def _physical_cores_from_osx_sysctl(self):
        import subprocess
        try:
            p = Popen(['sysctl', '-n', 'hw.physicalcpu'],
                      stdout=subprocess.PIPE,
                      stderr=subprocess.PIPE,
                      text=True)
        except (OSError, IOError):
            return None

        stdout, stderr = p.communicate()
        if p.returncode:
            return None

        return int(stdout.strip())
コード例 #12
0
    def subprocess(self, args, **subproc_kwargs):
        if self.manager:
            self.target_environ.update(self.manager.environ)

        shell_mode = isinstance(args, basestring)
        return Popen(args,
                     shell=shell_mode,
                     env=self.target_environ,
                     **subproc_kwargs)
コード例 #13
0
def get_system_info():
    """Get system info that might affect resolve time.
    """
    from rez import __version__
    from rez.utils.execution import Popen
    from rez.solver import SOLVER_VERSION

    info = {
        "rez_version": __version__,
        "rez_solver_version": SOLVER_VERSION,
        "py_version": "%d.%d" % sys.version_info[:2],
        "platform": platform.platform()
    }

    # this may only work on linux, but that's ok - the important thing is that
    # it works in the benchmark workflow, and we run that on linux only
    #
    try:
        proc = Popen(["cat", "/proc/cpuinfo"],
                     stdout=subprocess.PIPE,
                     text=True)
        out, _ = proc.communicate()

        if proc.returncode == 0:
            # parse output, lines are like 'field : value'
            fields = {}
            for line in out.strip().split('\n'):
                if ':' not in line:
                    continue

                parts = line.strip().split(':', 1)
                key = parts[0].strip()
                value = parts[1].strip()
                fields[key] = value

            # get the bits we care about
            info["num_cpu"] = int(fields["processor"]) + 1
            info["cpu"] = fields["model name"]
    except:
        pass

    return info
コード例 #14
0
    def open(self, section_index=0):
        """Launch a help section."""
        uri = self._sections[section_index][1]
        if len(uri.split()) == 1:
            self._open_url(uri)
        else:
            if self._verbose:
                print("running command: %s" % uri)

            with Popen(uri, shell=True) as p:
                p.wait()
コード例 #15
0
def run_benchmark():
    from rez import module_root_path
    from rez.utils.execution import Popen

    if os.path.exists(out_dir):
        print("Dir specified by --out (%s) must not exist" % out_dir,
              file=sys.stderr)
        sys.exit(1)

    os.mkdir(out_dir)
    print("Writing results to %s..." % out_dir)

    # extract package repo
    filepath = os.path.join(module_root_path, "data", "benchmarking",
                            "packages.tar.gz")
    proc = Popen(["tar", "-xf", filepath], cwd=out_dir)
    proc.wait()

    load_packages()
    do_resolves()
コード例 #16
0
ファイル: powershell_base.py プロジェクト: sparklabor/rez
    def get_syspaths(cls):
        if cls.syspaths is not None:
            return cls.syspaths

        if config.standard_system_paths:
            cls.syspaths = config.standard_system_paths
            return cls.syspaths

        # detect system paths using registry
        def gen_expected_regex(parts):
            whitespace = r"[\s]+"
            return whitespace.join(parts)

        # TODO: Research if there is an easier way to pull system PATH from
        # registry in powershell
        paths = []

        cmd = [
            "REG", "QUERY",
            ("HKLM\\SYSTEM\\CurrentControlSet\\"
             "Control\\Session Manager\\Environment"), "/v", "PATH"
        ]

        expected = gen_expected_regex([
            ("HKEY_LOCAL_MACHINE\\\\SYSTEM\\\\CurrentControlSet\\\\"
             "Control\\\\Session Manager\\\\Environment"), "PATH",
            "REG_(EXPAND_)?SZ", "(.*)"
        ])

        p = Popen(cmd, stdout=PIPE, stderr=PIPE,
                  shell=True, text=True)
        out_, _ = p.communicate()
        out_ = out_.strip()

        if p.returncode == 0:
            match = re.match(expected, out_)
            if match:
                paths.extend(match.group(2).split(os.pathsep))

        cmd = ["REG", "QUERY", "HKCU\\Environment", "/v", "PATH"]

        expected = gen_expected_regex([
            "HKEY_CURRENT_USER\\\\Environment", "PATH", "REG_(EXPAND_)?SZ",
            "(.*)"
        ])

        p = Popen(cmd, stdout=PIPE, stderr=PIPE,
                  shell=True, text=True)
        out_, _ = p.communicate()
        out_ = out_.strip()

        if p.returncode == 0:
            match = re.match(expected, out_)
            if match:
                paths.extend(match.group(2).split(os.pathsep))

        cls.syspaths = [x for x in paths if x]

        return cls.syspaths
コード例 #17
0
def run_pip_command(command_args, pip_version=None, python_version=None):
    """Run a pip command.
    Args:
        command_args (list of str): Args to pip.
    Returns:
        `subprocess.Popen`: Pip process.
    """
    py_exe, context = find_pip(pip_version, python_version)
    command = [py_exe, "-m", "pip"] + list(command_args)

    if context is None:
        return Popen(command)
    else:
        return context.execute_shell(command=command, block=False)
コード例 #18
0
def command(opts, parser, extra_arg_groups=None):
    from rez.cli._main import is_hyphened_command
    from rez.utils.execution import Popen
    import sys

    # We need to skip first arg if 'rez-python' form was used, but we need to
    # skip the first TWO args if 'rez python' form was used.
    #
    if is_hyphened_command():
        args = sys.argv[1:]
    else:
        args = sys.argv[2:]

    cmd = [sys.executable, "-E"] + args

    with Popen(cmd) as p:
        sys.exit(p.wait())
コード例 #19
0
def view_graph(graph_str, dest_file=None):
    """View a dot graph in an image viewer."""
    from rez.system import system
    from rez.config import config

    if (system.platform == "linux") and (not os.getenv("DISPLAY")):
        print("Unable to open display.", file=sys.stderr)
        sys.exit(1)

    dest_file = _write_graph(graph_str, dest_file=dest_file)

    # view graph
    viewed = False
    prog = config.image_viewer or 'browser'
    print("loading image viewer (%s)..." % prog)

    if config.image_viewer:
        with Popen([config.image_viewer, dest_file]) as p:
            p.wait()
        viewed = not bool(p.returncode)

    if not viewed:
        import webbrowser
        webbrowser.open_new("file://" + dest_file)
コード例 #20
0
ファイル: _bez.py プロジェクト: zclongpop123/rez
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(), Loader=yaml.FullLoader)

    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 = \
    """
    env={}
    with open("%(buildfile)s") as stream:
        exec(compile(stream.read(), stream.name, 'exec'), env)

    buildfunc = env.get("build")
    if not buildfunc:
        import sys
        sys.stderr.write("Did not find function 'build' in rezbuild.py\\n")
        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

    if hasattr(inspect, "getfullargspec"):
        # support py3 kw-only args
        spec = inspect.getfullargspec(buildfunc)
        args = spec.args + spec.kwonlyargs
    else:
        args = inspect.getargspec(buildfunc).args

    kwargs = dict((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]

    with Popen(cmd) as p:
        p.wait()

    tmpdir_manager.clear()
    sys.exit(p.returncode)
コード例 #21
0
ファイル: cmd.py プロジェクト: sdot-b/rez
    def spawn_shell(self,
                    context_file,
                    tmpdir,
                    rcfile=None,
                    norc=False,
                    stdin=False,
                    command=None,
                    env=None,
                    quiet=False,
                    pre_command=None,
                    add_rez=True,
                    **Popen_args):

        command = self._expand_alias(command)
        startup_sequence = self.get_startup_sequence(rcfile, norc, bool(stdin),
                                                     command)
        shell_command = None

        def _record_shell(ex, files, bind_rez=True, print_msg=False):
            ex.source(context_file)
            if startup_sequence["envvar"]:
                ex.unsetenv(startup_sequence["envvar"])
            if add_rez and bind_rez:
                ex.interpreter._bind_interactive_rez()
            if print_msg and add_rez and not quiet:
                ex.info('')
                ex.info('You are now in a rez-configured environment.')
                ex.info('')
                if system.is_production_rez_install:
                    # previously this was called with the /K flag, however
                    # that would leave spawn_shell hung on a blocked call
                    # waiting for the user to type "exit" into the shell that
                    # was spawned to run the rez context printout
                    ex.command("cmd /Q /C rez context")

        def _create_ex():
            return RexExecutor(interpreter=self.new_shell(),
                               parent_environ={},
                               add_default_namespaces=False)

        executor = _create_ex()

        if self.settings.prompt:
            executor.interpreter._saferefenv('REZ_ENV_PROMPT')
            executor.env.REZ_ENV_PROMPT = \
                expandable("%REZ_ENV_PROMPT%").literal(self.settings.prompt)

        # Make .py launch within cmd without extension.
        if self.settings.additional_pathext:
            # Ensure that the PATHEXT does not append duplicates.
            fmt = (
                'echo %PATHEXT%|C:\\Windows\\System32\\findstr.exe /i /c:"{0}">nul '
                '|| set PATHEXT=%PATHEXT%;{0}')

            for pathext in self.settings.additional_pathext:
                executor.command(fmt.format(pathext))
            # This resets the errorcode, which is tainted by the code above
            executor.command("(call )")

        if startup_sequence["command"] is not None:
            _record_shell(executor, files=startup_sequence["files"])
            shell_command = startup_sequence["command"]
        else:
            _record_shell(executor,
                          files=startup_sequence["files"],
                          print_msg=(not quiet))

        if shell_command:
            # Launch the provided command in the configured shell and wait
            # until it exits.
            executor.command(shell_command)

        # Test for None specifically because resolved_context.execute_rex_code
        # passes '' and we do NOT want to keep a shell open during a rex code
        # exec operation.
        elif shell_command is None:
            # Launch the configured shell itself and wait for user interaction
            # to exit.
            executor.command('cmd /Q /K')

        # Exit the configured shell.
        executor.command('exit %errorlevel%')

        code = executor.get_output()
        target_file = os.path.join(tmpdir,
                                   "rez-shell.%s" % self.file_extension())

        with open(target_file, 'w') as f:
            f.write(code)

        if startup_sequence["stdin"] and stdin and (stdin is not True):
            Popen_args["stdin"] = stdin

        cmd = []
        if pre_command:
            if isinstance(pre_command, basestring):
                cmd = pre_command.strip().split()
            else:
                cmd = pre_command

        # Test for None specifically because resolved_context.execute_rex_code
        # passes '' and we do NOT want to keep a shell open during a rex code
        # exec operation.
        if shell_command is None:
            cmd_flags = ['/Q', '/K']
        else:
            cmd_flags = ['/Q', '/C']

        cmd += [self.executable]
        cmd += cmd_flags
        cmd += ['call {}'.format(target_file)]
        is_detached = (cmd[0] == 'START')

        p = Popen(cmd, env=env, shell=is_detached, **Popen_args)
        return p
コード例 #22
0
    def _os(self):
        """
        Note: We cannot replace this with 'distro.linux_distribution' in
        entirety as unfortunately there are slight differences. Eg our code
        gives 'Ubuntu-16.04' whereas distro gives 'ubuntu-16.04'.
        """
        distributor = None
        release = None

        def _str(s):
            if (s.startswith("'") and s.endswith("'")) \
                    or (s.startswith('"') and s.endswith('"')):
                return s[1:-1]
            else:
                return s

        def _os():
            if distributor and release:
                return "%s-%s" % (distributor, release)
            else:
                return None

        def _parse(txt, distributor_key, release_key):
            distributor_ = None
            release_ = None
            lines = txt.strip().split('\n')
            for line in lines:
                if line.startswith(distributor_key):
                    s = line[len(distributor_key):].strip()
                    distributor_ = _str(s)
                elif line.startswith(release_key):
                    s = line[len(release_key):].strip()
                    release_ = _str(s)
            return distributor_, release_

        # first try parsing the /etc/lsb-release file
        file = "/etc/lsb-release"
        if os.path.isfile(file):
            with open(file) as f:
                txt = f.read()
            distributor, release = _parse(txt, "DISTRIB_ID=",
                                          "DISTRIB_RELEASE=")
            result = _os()
            if result:
                return result

        # next, try getting the output of the lsb_release program
        import subprocess

        p = Popen(['/usr/bin/env', 'lsb_release', '-a'],
                  stdout=subprocess.PIPE,
                  stderr=subprocess.PIPE,
                  text=True)
        txt = p.communicate()[0]

        if not p.returncode:
            distributor_, release_ = _parse(txt, "Distributor ID:", "Release:")
            if distributor_ and not distributor:
                distributor = distributor_
            if release_ and not release:
                release = release_

            result = _os()
            if result:
                return result

        # try to read the /etc/os-release file
        # this file contains OS specific data on linux
        # distributions
        # see https://www.freedesktop.org/software/systemd/man/os-release.html
        os_release = '/etc/os-release'
        if os.path.isfile(os_release):
            with open(os_release, 'r') as f:
                txt = f.read()
            distributor_, release_ = _parse(txt, "ID=", "VERSION_ID=")
            if distributor_ and not distributor:
                distributor = distributor_
            if release_ and not release:
                release = release_

            result = _os()
            if result:
                return result

        # use distro lib
        from rez.vendor.distro import distro

        parts = distro.linux_distribution(full_distribution_name=False)
        if parts[0] == '':
            raise RezSystemError("cannot detect operating system")
        return '-'.join(parts[:2])
コード例 #23
0
    def spawn_shell(self,
                    context_file,
                    tmpdir,
                    rcfile=None,
                    norc=False,
                    stdin=False,
                    command=None,
                    env=None,
                    quiet=False,
                    pre_command=None,
                    add_rez=True,
                    package_commands_sourced_first=None,
                    **Popen_args):

        d = self.get_startup_sequence(rcfile, norc, bool(stdin), command)
        envvar = d["envvar"]
        files = d["files"]
        bind_files = d["bind_files"]
        do_rcfile = d["do_rcfile"]
        shell_command = None

        if package_commands_sourced_first is None:
            package_commands_sourced_first = config.package_commands_sourced_first

        def _record_shell(ex, files, bind_rez=True, print_msg=False):
            if bind_rez and package_commands_sourced_first:
                ex.source(context_file)

            for file_ in files:
                if os.path.exists(os.path.expanduser(file_)):
                    ex.source(file_)

            if bind_rez and not package_commands_sourced_first:
                ex.source(context_file)

            if envvar:
                ex.unsetenv(envvar)
            if add_rez and bind_rez:
                ex.interpreter._bind_interactive_rez()
            if print_msg and add_rez and not quiet:
                ex.info('')
                ex.info('You are now in a rez-configured environment.')
                ex.info('')
                if system.is_production_rez_install:
                    ex.command('rezolve context')

        def _write_shell(ex, filename):
            code = ex.get_output()
            target_file = os.path.join(tmpdir, filename)
            with open(target_file, 'w') as f:
                f.write(code)
            return target_file

        def _create_ex():
            return RexExecutor(interpreter=self.new_shell(),
                               parent_environ={},
                               add_default_namespaces=False)

        executor = _create_ex()

        if self.settings.prompt:
            newprompt = '${REZ_ENV_PROMPT}%s' % self.settings.prompt
            executor.interpreter._saferefenv('REZ_ENV_PROMPT')
            executor.env.REZ_ENV_PROMPT = newprompt

        if d["command"] is not None:
            _record_shell(executor, files=files)
            shell_command = d["command"]
        else:
            if d["stdin"]:
                assert (self.stdin_arg)
                shell_command = "%s %s" % (self.executable, self.stdin_arg)
                quiet = True
            elif do_rcfile:
                assert (self.rcfile_arg)
                shell_command = "%s %s" % (self.executable, self.rcfile_arg)
            else:
                shell_command = self.executable

            if do_rcfile:
                # hijack rcfile to insert our own script
                ex = _create_ex()
                _record_shell(ex, files=files, print_msg=(not quiet))
                filename = "rcfile.%s" % self.file_extension()
                filepath = _write_shell(ex, filename)
                shell_command += " %s" % filepath
            elif envvar:
                # hijack env-var to insert our own script
                ex = _create_ex()
                _record_shell(ex, files=files, print_msg=(not quiet))
                filename = "%s.%s" % (envvar, self.file_extension())
                filepath = _write_shell(ex, filename)
                executor.setenv(envvar, filepath)
            else:
                # hijack $HOME to insert our own script
                files = [x for x in files if x not in bind_files
                         ] + list(bind_files)

                if files:
                    for file_ in files:
                        if file_ in bind_files:
                            bind_rez = True
                            files_ = [file_] if d["source_bind_files"] else []
                        else:
                            bind_rez = False
                            files_ = [file_]

                        ex = _create_ex()
                        ex.setenv('HOME', os.environ.get('HOME', ''))
                        _record_shell(ex,
                                      files=files_,
                                      bind_rez=bind_rez,
                                      print_msg=bind_rez)
                        _write_shell(ex, os.path.basename(file_))

                    executor.setenv("HOME", tmpdir)

                    # keep history
                    if self.histfile and self.histvar:
                        histfile = os.path.expanduser(self.histfile)
                        if os.path.exists(histfile):
                            executor.setenv(self.histvar, histfile)
                else:
                    if config.warn("shell_startup"):
                        print_warning(
                            "WARNING: Could not configure environment from "
                            "within the target shell (%s); this has been done "
                            "in the parent process instead." % self.name())
                    executor.source(context_file)

        if shell_command:  # an empty string means 'run no command and exit'
            executor.command(shell_command)
        executor.command("exit %s" % self.last_command_status)

        code = executor.get_output()
        target_file = os.path.join(tmpdir,
                                   "rez-shell.%s" % self.file_extension())
        with open(target_file, 'w') as f:
            f.write(code)

        if d["stdin"] and stdin and (stdin is not True):
            Popen_args["stdin"] = stdin

        cmd = []
        if pre_command:
            if isinstance(pre_command, basestring):
                cmd = pre_command.strip().split()
            else:
                cmd = pre_command
        cmd.extend([self.executable, target_file])

        try:
            p = Popen(cmd, env=env, **Popen_args)
        except Exception as e:
            cmd_str = ' '.join(map(pipes.quote, cmd))
            raise RezSystemError("Error running command:\n%s\n%s" %
                                 (cmd_str, str(e)))
        return p
コード例 #24
0
    def _os(self):
        distributor = None
        release = None

        def _str(s):
            if (s.startswith("'") and s.endswith("'")) \
                    or (s.startswith('"') and s.endswith('"')):
                return s[1:-1]
            else:
                return s

        def _os():
            if distributor and release:
                return "%s-%s" % (distributor, release)
            else:
                return None

        def _parse(txt, distributor_key, release_key):
            distributor_ = None
            release_ = None
            lines = txt.strip().split('\n')
            for line in lines:
                if line.startswith(distributor_key):
                    s = line[len(distributor_key):].strip()
                    distributor_ = _str(s)
                elif line.startswith(release_key):
                    s = line[len(release_key):].strip()
                    release_ = _str(s)
            return distributor_, release_

        # first try parsing the /etc/lsb-release file
        file = "/etc/lsb-release"
        if os.path.isfile(file):
            with open(file) as f:
                txt = f.read()
            distributor, release = _parse(txt, "DISTRIB_ID=",
                                          "DISTRIB_RELEASE=")
            result = _os()
            if result:
                return result

        # next, try getting the output of the lsb_release program
        import subprocess

        p = Popen(['/usr/bin/env', 'lsb_release', '-a'],
                  stdout=subprocess.PIPE,
                  stderr=subprocess.PIPE,
                  text=True)
        txt = p.communicate()[0]

        if not p.returncode:
            distributor_, release_ = _parse(txt, "Distributor ID:", "Release:")
            if distributor_ and not distributor:
                distributor = distributor_
            if release_ and not release:
                release = release_

            result = _os()
            if result:
                return result

        # try to read the /etc/os-release file
        # this file contains OS specific data on linux
        # distributions
        # see https://www.freedesktop.org/software/systemd/man/os-release.html
        os_release = '/etc/os-release'
        if os.path.isfile(os_release):
            with open(os_release, 'r') as f:
                txt = f.read()
            distributor_, release_ = _parse(txt, "ID=", "VERSION_ID=")
            if distributor_ and not distributor:
                distributor = distributor_
            if release_ and not release:
                release = release_

            result = _os()
            if result:
                return result

        # last, use python's dist detection. It is known to return incorrect
        # info on some systems though
        try:
            distributor_, release_, _ = platform.linux_distribution()
        except:
            distributor_, release_, _ = platform.dist()

        if distributor_ and not distributor:
            distributor = distributor_
        if release_ and not release:
            release = release_

        result = _os()
        if result:
            return result

        # last resort, accept missing release
        if distributor:
            return distributor

        # give up
        raise RezSystemError("cannot detect operating system")
コード例 #25
0
ファイル: powershell_base.py プロジェクト: zclongpop123/rez
    def spawn_shell(self,
                    context_file,
                    tmpdir,
                    rcfile=None,
                    norc=False,
                    stdin=False,
                    command=None,
                    env=None,
                    quiet=False,
                    pre_command=None,
                    add_rez=True,
                    **Popen_args):

        startup_sequence = self.get_startup_sequence(rcfile, norc, bool(stdin),
                                                     command)
        shell_command = None

        def _record_shell(ex, files, bind_rez=True, print_msg=False):
            ex.source(context_file)
            if startup_sequence["envvar"]:
                ex.unsetenv(startup_sequence["envvar"])
            if add_rez and bind_rez:
                ex.interpreter._bind_interactive_rez()
            if print_msg and add_rez and not quiet:
                ex.info('')
                ex.info('You are now in a rez-configured environment.')
                ex.info('')
                if system.is_production_rez_install:
                    ex.command("rezolve context")

        executor = RexExecutor(interpreter=self.new_shell(),
                               parent_environ={},
                               add_default_namespaces=False)

        if startup_sequence["command"] is not None:
            _record_shell(executor, files=startup_sequence["files"])
            shell_command = startup_sequence["command"]
        else:
            _record_shell(executor,
                          files=startup_sequence["files"],
                          print_msg=(not quiet))

        self._additional_commands(executor)

        if shell_command:
            executor.command(shell_command)

        # Forward exit call to parent PowerShell process
        executor.command("exit $LastExitCode")

        code = executor.get_output()
        target_file = os.path.join(tmpdir,
                                   "rez-shell.%s" % self.file_extension())

        with open(target_file, 'w') as f:
            f.write(code)

        cmd = []
        if pre_command:
            cmd = pre_command

            if not isinstance(cmd, (tuple, list)):
                cmd = pre_command.rstrip().split()

        cmd += [self.executable]

        # Suppresses copyright message of PowerShell and pwsh
        cmd += ["-NoLogo"]

        # Generic form of sourcing that works in powershell and pwsh
        cmd += ["-File", target_file]

        if shell_command is None:
            cmd.insert(1, "-NoExit")

        p = Popen(cmd, env=env, **Popen_args)
        return p