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 []
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))
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()
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
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)
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)
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)
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)
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()
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
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())
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)
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
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()
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()
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
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)
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())
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)
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)
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
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])
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
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")
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