Example #1
0
def test_method_detection_requirements(tmp_path):
    """Test detecting installation method to be used - requirements."""
    with open(os.path.join(tmp_path, "requirements.txt"), "w"):
        pass

    work_dir = os.path.join(tmp_path, "requirements")
    os.makedirs(work_dir)
    with cwd(work_dir):
        flexmock(micropipenv).should_receive("install_requirements").once()
        micropipenv.install(method=None)
Example #2
0
def test_method_detection_pipenv(tmp_path):
    """Test detecting installation method to be used - Pipenv."""
    with open(os.path.join(tmp_path, "Pipfile.lock"), "w"):
        pass

    work_dir = os.path.join(tmp_path, "pipenv")
    os.makedirs(work_dir)
    with cwd(work_dir):
        flexmock(micropipenv).should_receive("install_pipenv").once()
        micropipenv.install(method=None)
Example #3
0
def test_method_detection_poetry(tmp_path):
    """Test detecting installation method to be used - Poetry."""
    # Touch files with specific names so that detection can find them.
    with open(os.path.join(tmp_path, "pyproject.toml"), "w"):
        pass

    with open(os.path.join(tmp_path, "poetry.lock"), "w"):
        pass

    work_dir = os.path.join(tmp_path, "poetry")
    os.makedirs(work_dir)
    with cwd(work_dir):
        flexmock(micropipenv).should_receive("install_poetry").once()
        micropipenv.install(method=None)
Example #4
0
def install(dev: bool) -> None:
    """Install dependencies as stated in Pipfile.lock or requirements.txt.

    This command assumes requirements files are present and dependencies are already resolved.
    If that's not the case, issue `thamos advise` before calling this.
    """
    with workdir():
        method = ("pipenv" if configuration.requirements_format == "pipenv"
                  else "requirements")

        if not dev and method == "pipenv":
            _LOGGER.warning(
                "Development dependencies will not be installed - see %s",
                jl("no_dev"))

        micropipenv.install(method=method, deploy=True, dev=dev)
Example #5
0
def install(
    runtime_environment_name: typing.Optional[str] = None,
    dev: bool = False,
    pip_args: typing.Optional[typing.Tuple[str]] = None,
) -> None:
    """Perform installation of packages for the given runtime environment.

    If the runtime environment is not specified, the first environment stated in the configuration is used.
    """
    method = ("pipenv" if thoth_config.requirements_format == "pipenv" else
              "requirements")

    if not dev and method == "pipenv":
        _LOGGER.warning(
            "Development dependencies will not be installed - see %s",
            jl("no_dev"))

    with cwd(thoth_config.get_overlays_directory(runtime_environment_name)):
        if method == "pipenv":
            if not os.path.isfile("Pipfile.lock"):
                raise NoRequirementsFile(
                    f"No Pipfile.lock found in {os.getcwd()!r} needed to install dependencies, "
                    "issue `thamos advise` resolve dpeendencies")
            if not os.path.isfile(
                    "Pipfile"):  # Required for computing digests.
                raise NoRequirementsFile(
                    f"No Pipfile found in {os.getcwd()!r} needed for the installation process"
                )
        else:
            if not os.path.isfile("requirements.txt"):
                raise NoRequirementsFile(
                    f"No requirements.txt file found in {os.getcwd()!r} needed to install dependencies"
                )

        _LOGGER.info(
            "Using %r installation method to install dependencies stated in %r",
            method,
            os.getcwd(),
        )
        micropipenv.install(method=method,
                            deploy=True,
                            dev=dev,
                            pip_args=pip_args)
Example #6
0
def advise(
    debug: bool = False,
    no_write: bool = False,
    recommendation_type: str = None,
    runtime_environment: str = None,
    no_wait: bool = False,
    no_static_analysis: bool = False,
    json_output: bool = False,
    force: bool = False,
    dev: bool = False,
    no_user_stack: bool = False,
    install: bool = False,
    write_advised_manifest_changes: Optional[str] = None,
):
    """Ask Thoth for recommendations on application stack."""
    if install and no_wait:
        _LOGGER.error("Cannot install dependencies as --no-wait was provided")
        sys.exit(1)
    if install and no_write:
        _LOGGER.error(
            "Cannot install dependencies if lock files are not written")
        sys.exit(1)

    with workdir():
        if not dev and configuration.requirements_format == "pipenv":
            _LOGGER.warning(
                "Development dependencies will not be considered during the resolution process - see %s",
                jl("no_dev"),
            )

        # In CLI we always call to obtain only the best software stack (count is implicitly set to 1).
        results = thoth_advise_here(
            recommendation_type=recommendation_type,
            runtime_environment_name=runtime_environment,
            debug=debug,
            nowait=no_wait,
            force=force,
            source_type=ThothAdviserIntegrationEnum.CLI,
            no_static_analysis=no_static_analysis,
            dev=dev,
            no_user_stack=no_user_stack,
        )

        if not results:
            return sys.exit(2)

        if no_wait:
            # Echo the analysis id to user when not waiting.
            click.echo(results)
            sys.exit(0)

        result, error = results
        if error:
            if json_output:
                json.dump(result, sys.stdout, indent=2)
            else:
                stack_info = (result.get("report") or {}).get("stack_info")
                if stack_info:
                    _print_report(
                        stack_info,
                        json_output=json_output,
                        title="Application stack guidance",
                    )
                print(
                    result.get("error_msg")
                    or "No error message was provided by the service.")

            sys.exit(4)

        if not no_write:
            if result["report"] and result["report"]["stack_info"]:
                _print_report(
                    result["report"]["stack_info"],
                    json_output=json_output,
                    title="Application stack guidance",
                )

            # Print report of the best one - thus index zero.
            if result["report"] and result["report"]["products"]:
                if result["report"]["products"][0]["justification"]:
                    _print_report(
                        result["report"]["products"][0]["justification"],
                        json_output=json_output,
                        title="Recommended stack report",
                    )
                else:
                    click.echo(
                        "No justification was made for the recommended stack")

            pipfile = result["report"]["products"][0]["project"][
                "requirements"]
            pipfile_lock = result["report"]["products"][0]["project"][
                "requirements_locked"]
            _write_configuration(
                result["report"]["products"][0]["advised_runtime_environment"],
                recommendation_type,
                dev,
            )
            _write_files(pipfile, pipfile_lock,
                         configuration.requirements_format)  # type: ignore

            if write_advised_manifest_changes:
                advised_manifest_changes = result["report"]["products"][0][
                    "project"].get("advised_manifest_changes")
                with open(write_advised_manifest_changes,
                          "w") as advised_manifest_changes_file:
                    json.dump(advised_manifest_changes or {},
                              advised_manifest_changes_file)
                    advised_manifest_changes_file.write("\n")

            if install:
                method = ("pipenv" if configuration.requirements_format
                          == "pipenv" else "requirements")
                micropipenv.install(method=method, deploy=True, dev=dev)
        else:
            click.echo(json.dumps(result, indent=2))

    sys.exit(0)