Ejemplo n.º 1
0
def create_virtual_env(current_dir: str):
    """
    Raises:
        OpenCaosFileException
        InvalidCaosFileFormat
        WrongKeyTypeInYamlFile
        CreateVirtualEnvironmentException
        MissingBinaryException
    """
    env_name = get_virtual_environment_from_yaml()
    env_path: str = os.path.abspath(current_dir + "/" + env_name)
    if os.path.isdir(env_path):
        caos_command_print(
            command=NAME,
            message=INFO_MESSAGE(
                "The virtual environment already exists so a new one won't be created"
            ))

    else:
        caos_command_print(
            command=NAME,
            message=INFO_MESSAGE("Creating a new virtual environment..."))
        create_env_process: subprocess.CompletedProcess = subprocess.run(
            [
                sys.executable, "-m", DEFAULT_VIRTUAL_ENVIRONMENT_NAME,
                os.path.abspath(get_current_dir() + "/" + env_name)
            ],
            stderr=subprocess.PIPE,
            stdout=subprocess.PIPE,
            universal_newlines=True)

        if create_env_process.returncode != 0:
            raise CreateVirtualEnvironmentException(create_env_process.stderr)

        caos_command_print(
            command=NAME,
            message=SUCCESS_MESSAGE("A new virtual environment was created"))

    if is_win_os():
        pip_path: str = PIP_PATH_VENV_WIN.replace(
            DEFAULT_VIRTUAL_ENVIRONMENT_NAME, env_name)
        python_path: str = PYTHON_PATH_VENV_WIN.replace(
            DEFAULT_VIRTUAL_ENVIRONMENT_NAME, env_name)

    if is_posix_os():
        pip_path: str = PIP_PATH_VENV_POSIX.replace(
            DEFAULT_VIRTUAL_ENVIRONMENT_NAME, env_name)
        python_path: str = PYTHON_PATH_VENV_POSIX.replace(
            DEFAULT_VIRTUAL_ENVIRONMENT_NAME, env_name)

    if not os.path.isfile(pip_path):
        caos_command_print(
            command=NAME,
            message=WARNING_MESSAGE(
                "The virtual environment does not have a 'pip' binary"))

    if not os.path.isfile(python_path):
        raise_missing_python_binary_exception(env_name=env_name)
Ejemplo n.º 2
0
def supports_color() -> bool:
    """
    Returns True if the running system's terminal supports color, and False
    otherwise.
    """
    supported_platform = is_posix_os() or (is_win_os() and load_colorama())
    is_a_tty = hasattr(
        sys.stdout,
        'isatty') and sys.stdout.isatty()  # isatty is not always present
    return supported_platform and is_a_tty
Ejemplo n.º 3
0
    def test_update_command(self):
        exit_code: int = command_init.entry_point(args=[])
        self.assertEqual(0, exit_code)

        if is_win_os():
            self.assertTrue(os.path.isfile(PYTHON_PATH_VENV_WIN))
            self.assertTrue(os.path.isfile(PIP_PATH_VENV_WIN))
            python_path = PYTHON_PATH_VENV_WIN

        elif is_posix_os():
            self.assertTrue(os.path.isfile(PYTHON_PATH_VENV_POSIX))
            self.assertTrue(os.path.isfile(PIP_PATH_VENV_POSIX))
            python_path = PYTHON_PATH_VENV_POSIX

        self.assertTrue(
            os.path.isfile(os.path.abspath(_CURRENT_DIR + "/caos.yml")))
        with open(os.path.abspath(_CURRENT_DIR + "/caos.yml"), "w") as file:
            file.write("""
            virtual_environment: "venv"
            dependencies:
                pip: "latest"
                requests: "2.0.0"  
                numpy: "^1.18.2"
                flask: "~1.1.0"            
            """)

        exit_code: int = command_update.entry_point(args=[])
        self.assertEqual(0, exit_code)
        messages: str = escape_ansi(self.new_stdout.getvalue())

        self.assertIn("INFO: Updating PIP...", messages)
        self.assertIn("SUCCESS: PIP was successfully updated", messages)
        self.assertIn("INFO: Installing dependencies...", messages)
        self.assertIn("SUCCESS: All dependencies have been installed",
                      messages)

        pip_list_process: subprocess.CompletedProcess = subprocess.run(
            [python_path, "-m", "pip", "list"],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            universal_newlines=True)

        if pip_list_process.returncode != 0:
            self.fail("pip list failed")

        output: str = pip_list_process.stdout.lower()
        self.assertIn("pip", output)
        self.assertIn("requests", output)
        self.assertIn("numpy", output)
        self.assertIn("flask", output)
Ejemplo n.º 4
0
    def test_pip_command_missing_binary(self):
        exit_code: int = command_init.entry_point(args=[])
        self.assertEqual(0, exit_code)

        if is_win_os():
            self.assertTrue(os.path.isfile(PIP_PATH_VENV_WIN))
            os.remove(PIP_PATH_VENV_WIN)

        elif is_posix_os():
            self.assertTrue(os.path.isfile(PIP_PATH_VENV_POSIX))
            os.remove(PIP_PATH_VENV_POSIX)

        with self.assertRaises(MissingBinaryException) as context:
            command_pip.entry_point(args=["search", "caos"])
        self.assertIn(_MISSING_PIP_BINARY_MESSAGE, str(context.exception))
Ejemplo n.º 5
0
    def test_python_command_missing_binary(self):
        exit_code: int = command_init.entry_point(args=[])
        self.assertEqual(0, exit_code)

        if is_win_os():
            self.assertTrue(os.path.isfile(PYTHON_PATH_VENV_WIN))
            os.remove(PYTHON_PATH_VENV_WIN)

        elif is_posix_os():
            self.assertTrue(os.path.isfile(PYTHON_PATH_VENV_POSIX))
            os.remove(PYTHON_PATH_VENV_POSIX)

        with self.assertRaises(MissingBinaryException) as context:
            command_python.entry_point(args=["-c", "print('Hello World')"])
        self.assertIn(_MISSING_PYTHON_BINARY_MESSAGE, str(context.exception))
Ejemplo n.º 6
0
    def test_init_command_venv_binaries(self):
        exit_code: int = command_init.entry_point(args=[""])
        self.assertEqual(0, exit_code)
        if is_win_os():
            self.assertTrue(os.path.isfile(PYTHON_PATH_VENV_WIN))
            self.assertTrue(os.path.isfile(PIP_PATH_VENV_WIN))
            os.remove(PYTHON_PATH_VENV_WIN)
            os.remove(PIP_PATH_VENV_WIN)

        elif is_posix_os():
            self.assertTrue(os.path.isfile(PYTHON_PATH_VENV_POSIX))
            self.assertTrue(os.path.isfile(PIP_PATH_VENV_POSIX))
            os.remove(PYTHON_PATH_VENV_POSIX)
            os.remove(PIP_PATH_VENV_POSIX)

        self._restore_stdout()
        self._redirect_stdout()
        with self.assertRaises(MissingBinaryException) as context:
            command_init.entry_point(args=[])
        self.assertIn(_MISSING_PYTHON_ERROR_MESSAGE, str(context.exception))
Ejemplo n.º 7
0
def main(args: List[str]) -> ExitCode:
    current_dir: str = get_current_dir()
    if not os.path.isfile(
            os.path.abspath(current_dir + "/" + CAOS_YAML_FILE_NAME)):
        raise_missing_yaml_exception()

    venv_name: str = get_virtual_environment_from_yaml()

    if not os.path.isdir(os.path.abspath(current_dir + "/" + venv_name)):
        raise_missing_virtual_environment_exception(env_name=venv_name)

    if is_win_os():
        python_path: str = PYTHON_PATH_VENV_WIN.replace(
            DEFAULT_VIRTUAL_ENVIRONMENT_NAME, venv_name)
    elif is_posix_os():
        python_path: str = PYTHON_PATH_VENV_POSIX.replace(
            DEFAULT_VIRTUAL_ENVIRONMENT_NAME, venv_name)

    if not os.path.isfile(python_path):
        raise_missing_python_binary_exception(env_name=venv_name)

    # The current Unittest for this redirects the stdout to a StringIO() buffer, which is not compatible with
    # subprocess, so for this scenario a subprocess.PIPE is used instead of the sys.stdout to be able to capture
    # the output in the unittests
    is_unittest: bool = True if isinstance(sys.stdout, StringIO) else False
    python_process: subprocess.CompletedProcess = subprocess.run(
        [python_path] + args,
        stdout=subprocess.PIPE if is_unittest else sys.stdout,
        stderr=subprocess.STDOUT,
        stdin=sys.stdin,
        universal_newlines=True)

    if is_unittest and python_process.stdout:
        print(python_process.stdout)

    return ExitCode(python_process.returncode)
Ejemplo n.º 8
0
def main(args: List[str]) -> ExitCode:
    current_dir: str = get_current_dir()
    if not os.path.isfile(os.path.abspath(current_dir + "/" + CAOS_YAML_FILE_NAME)):
        raise_missing_yaml_exception()

    venv_name: str = get_virtual_environment_from_yaml()

    if not os.path.isdir(os.path.abspath(current_dir + "/" + venv_name)):
        raise_missing_virtual_environment_exception(env_name=venv_name)

    if is_win_os():
        pip_path: str = PIP_PATH_VENV_WIN.replace(DEFAULT_VIRTUAL_ENVIRONMENT_NAME, venv_name)
        python_path: str = PYTHON_PATH_VENV_WIN.replace(DEFAULT_VIRTUAL_ENVIRONMENT_NAME, venv_name)
    elif is_posix_os():
        pip_path: str = PIP_PATH_VENV_POSIX.replace(DEFAULT_VIRTUAL_ENVIRONMENT_NAME, venv_name)
        python_path: str = PYTHON_PATH_VENV_POSIX.replace(DEFAULT_VIRTUAL_ENVIRONMENT_NAME, venv_name)

    if not os.path.isfile(pip_path):
        raise_missing_pip_binary_exception(env_name=venv_name)
    if not os.path.isfile(python_path):
        raise_missing_python_binary_exception(env_name=venv_name)

    if args:
        caos_command_print(
            command=NAME,
            message=WARNING_MESSAGE("The update command does not support arguments")
        )

    dependencies: Dependencies = get_dependencies_from_yaml()

    is_unittest: bool = True if isinstance(sys.stdout, StringIO) else False

    if "pip" in dependencies:
        if "pip" == dependencies.get("pip"):
            dep: str = "pip"
        else:
            dep: str = "pip{}".format(dependencies.get("pip"))

        caos_command_print(
            command=NAME,
            message=INFO_MESSAGE("Updating PIP...")
        )

        del dependencies["pip"]

        install_pip_process: subprocess.CompletedProcess = subprocess.run(
            [python_path, "-m", "pip", "install", "--force-reinstall", dep],
            stdout=subprocess.PIPE if is_unittest else sys.stdout,
            stderr=subprocess.STDOUT,
            universal_newlines=True
        )

        if install_pip_process.returncode != 0:
            caos_command_print(
                command=NAME,
                message=WARNING_MESSAGE("PIP could not be updated")
            )
        else:
            caos_command_print(
                command=NAME,
                message=SUCCESS_MESSAGE("PIP was successfully updated")
            )

    if not dependencies:
        caos_command_print(
            command=NAME,
            message=INFO_MESSAGE("No dependencies to install")
        )
        return ExitCode(0)

    deps: List[str] = []
    for dep_name, dep_version in dependencies.items():
        if dep_name == dep_version:
            dep = dep_name
        elif dep_version.endswith(".whl") or dep_version.endswith(".dist-info") or dep_version.endswith(".tar.gz"):
            dep = dep_version
        else:
            dep = "{}{}".format(dep_name, dep_version)

        deps.append(dep)

    caos_command_print(
        command=NAME,
        message=INFO_MESSAGE("Installing dependencies...")
    )

    install_deps_process: subprocess.CompletedProcess = subprocess.run(
        [python_path, "-m", "pip", "install", "--force-reinstall"] + deps,
        stdout=subprocess.PIPE if is_unittest else sys.stdout,
        stderr=subprocess.STDOUT,
        universal_newlines=True
    )

    if install_deps_process.returncode != 0:
        caos_command_print(
            command=NAME,
            message=ERROR_MESSAGE("It was not possible to install the dependencies")
        )

        return ExitCode(install_deps_process.returncode)

    caos_command_print(
        command=NAME,
        message=SUCCESS_MESSAGE("All dependencies have been installed")
    )

    return ExitCode(0)
Ejemplo n.º 9
0
def main(args: List[str]) -> ExitCode:
    current_dir: str = get_current_dir()
    if not os.path.isfile(
            os.path.abspath(current_dir + "/" + CAOS_YAML_FILE_NAME)):
        raise_missing_yaml_exception()

    venv_name: str = get_virtual_environment_from_yaml()

    if not os.path.isdir(os.path.abspath(current_dir + "/" + venv_name)):
        raise_missing_virtual_environment_exception(env_name=venv_name)

    if is_win_os():
        pip_path: str = PIP_PATH_VENV_WIN.replace(
            DEFAULT_VIRTUAL_ENVIRONMENT_NAME, venv_name)
        python_path: str = PYTHON_PATH_VENV_WIN.replace(
            DEFAULT_VIRTUAL_ENVIRONMENT_NAME, venv_name)
    elif is_posix_os():
        pip_path: str = PIP_PATH_VENV_POSIX.replace(
            DEFAULT_VIRTUAL_ENVIRONMENT_NAME, venv_name)
        python_path: str = PYTHON_PATH_VENV_POSIX.replace(
            DEFAULT_VIRTUAL_ENVIRONMENT_NAME, venv_name)

    if not os.path.isfile(pip_path):
        raise_missing_pip_binary_exception(env_name=venv_name)

    if not os.path.isfile(python_path):
        raise_missing_python_binary_exception(env_name=venv_name)

    if args:
        caos_command_print(command=NAME,
                           message=WARNING_MESSAGE(
                               "The check command does not support arguments"))

    yaml_deps: Dependencies = get_dependencies_from_yaml()
    if not yaml_deps:
        caos_command_print(
            command=NAME,
            message=WARNING_MESSAGE(
                "There are no dependencies defined in the '{}' file".format(
                    CAOS_YAML_FILE_NAME)))
        return ExitCode(0)

    pip_list_process: subprocess.CompletedProcess = subprocess.run(
        [python_path, "-m", "pip", "list"],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        universal_newlines=True)

    if pip_list_process.returncode != 0 and pip_list_process.stderr:
        caos_command_print(
            command=NAME,
            message=ERROR_MESSAGE(
                "It was not possible to check the virtual environment dependencies"
            ))
        return ExitCode(1)

    pip_list_dependency_regex = re.compile(
        "^(?P<name>.+)(( )+)(\()?(?P<version>((\d+)(\.\d+)?(\.\d+)?))(\))?$")
    pip_list_output_by_lines = [
        line.strip() for line in pip_list_process.stdout.split("\n")
    ]

    installed_deps: Dependencies = {}
    for line in pip_list_output_by_lines:
        dep = pip_list_dependency_regex.match(line)
        if dep:
            installed_deps[dep.group("name").strip().lower()] = dep.group(
                "version").strip()

    not_installed_deps: List[str] = []
    for dep in yaml_deps:
        pip_dep = dep.replace("_", "-")
        if pip_dep not in installed_deps:
            not_installed_deps.append(dep)

    if not_installed_deps:
        not_installed_deps = ["'{}'".format(dep) for dep in not_installed_deps]
        caos_command_print(
            command=NAME,
            message=ERROR_MESSAGE(
                "The following dependencies are not installed in the virtual environment: {}"
                .format(", ".join(not_installed_deps))))
        return ExitCode(1)

    caos_command_print(
        command=NAME,
        message=SUCCESS_MESSAGE(
            "All dependencies are installed in the virtual environment"))

    return ExitCode(0)