Beispiel #1
0
def unix_path(path, path_flavor=None):
    """"Used to translate windows paths to MSYS unix paths like
    c/users/path/to/file. Not working in a regular console or MinGW!"""
    if not path:
        return None

    if os.path.exists(path):
        path = get_cased_path(
            path
        )  # if the path doesn't exist (and abs) we cannot guess the casing

    path_flavor = path_flavor or OSInfo.detect_windows_subsystem() or MSYS2
    path = path.replace(":/", ":\\")
    pattern = re.compile(r'([a-z]):\\', re.IGNORECASE)
    path = pattern.sub('/\\1/', path).replace('\\', '/')
    if path_flavor in (MSYS, MSYS2):
        return path.lower()
    elif path_flavor == CYGWIN:
        return '/cygdrive' + path.lower()
    elif path_flavor == WSL:
        return '/mnt' + path[0:2].lower() + path[2:]
    elif path_flavor == SFU:
        path = path.lower()
        return '/dev/fs' + path[0] + path[1:].capitalize()
    return None
Beispiel #2
0
 def detect_windows_subsystem_test(self):
     # Dont raise test
     result = OSInfo.detect_windows_subsystem()
     if not OSInfo.bash_path() or platform.system() != "Windows":
         self.assertEqual(None, result)
     else:
         self.assertEqual(str, type(result))
Beispiel #3
0
def run_in_windows_bash(conanfile,
                        bashcmd,
                        cwd=None,
                        subsystem=None,
                        msys_mingw=True,
                        env=None):
    """ Will run a unix command inside a bash terminal
        It requires to have MSYS2, CYGWIN, or WSL
    """
    env = env or {}
    if platform.system() != "Windows":
        raise ConanException("Command only for Windows operating system")
    subsystem = subsystem or OSInfo.detect_windows_subsystem()

    if not subsystem:
        raise ConanException(
            "Cannot recognize the Windows subsystem, install MSYS2/cygwin "
            "or specify a build_require to apply it.")

    if subsystem == MSYS2 and msys_mingw:
        # This needs to be set so that msys2 bash profile will set up the environment correctly.
        env_vars = {
            "MSYSTEM": ("MINGW32" if conanfile.settings.get_safe("arch")
                        == "x86" else "MINGW64"),
            "MSYS2_PATH_TYPE":
            "inherit"
        }
    else:
        env_vars = {}

    with environment_append(env_vars):

        hack_env = ""
        # In the bash.exe from WSL this trick do not work, always the /usr/bin etc at first place
        if subsystem != WSL:

            def get_path_value(container, subsystem_name):
                """Gets the path from the container dict and returns a string with the path for the subsystem_name"""
                _path_key = next(
                    (name
                     for name in container.keys() if "path" == name.lower()),
                    None)
                if _path_key:
                    _path_value = container.get(_path_key)
                    if isinstance(_path_value, list):
                        return ":".join([
                            unix_path(path, path_flavor=subsystem_name)
                            for path in _path_value
                        ])
                    else:
                        return unix_path(_path_value,
                                         path_flavor=subsystem_name)

            # First get the PATH from the conanfile.env
            inherited_path = get_path_value(conanfile.env, subsystem)
            # Then get the PATH from the real env
            env_path = get_path_value(env, subsystem)

            # Both together
            full_env = ":".join(v for v in [env_path, inherited_path] if v)
            # Put the build_requires and requires path at the first place inside the shell
            hack_env = ' && PATH="%s:$PATH"' % full_env if full_env else ""

        for var_name, value in env.items():
            if var_name == "PATH":
                continue
            hack_env += ' && %s=%s' % (var_name, value)

        # Needed to change to that dir inside the bash shell
        if cwd and not os.path.isabs(cwd):
            cwd = os.path.join(get_cwd(), cwd)

        curdir = unix_path(cwd or get_cwd(), path_flavor=subsystem)
        to_run = 'cd "%s"%s && %s ' % (curdir, hack_env, bashcmd)
        bash_path = OSInfo.bash_path()
        bash_path = '"%s"' % bash_path if " " in bash_path else bash_path
        wincmd = '%s --login -c %s' % (bash_path, escape_windows_cmd(to_run))
        conanfile.output.info('run_in_windows_bash: %s' % wincmd)

        # If is there any other env var that we know it contains paths, convert it to unix_path
        used_special_vars = [
            var for var in ["AR", "AS", "RANLIB", "LD", "STRIP", "CC", "CXX"]
            if var in conanfile.env.keys()
        ]
        normalized_env = {
            p: unix_path(conanfile.env[p], path_flavor=subsystem)
            for p in used_special_vars
        }

        # https://github.com/conan-io/conan/issues/2839 (subprocess=True)
        with environment_append(normalized_env):
            return conanfile._conan_runner(wincmd,
                                           output=conanfile.output,
                                           subprocess=True)