Exemple #1
0
def conda_update(
    name: str,
    specs: ListLike = (),
    channels: ListLike = None,
    all=False,
    yes: bool = False,
    strict_channel_priority: bool = True,
) -> Environment:
    """Install conda packages into the environment."""
    env = Environment.read(name=name)
    cleaned = process_specs(specs)
    if all:
        CondaHandler(env=env).update_all(
            packages=cleaned,
            channels=channels,
            yes=yes,
            strict_channel_priority=strict_channel_priority,
        )
    else:
        CondaHandler(env=env).install(
            packages=cleaned,
            channels=channels,
            yes=yes,
            strict_channel_priority=strict_channel_priority,
        )
    _ask_user_to_sync(name=name, yes=yes)
    return env
def test_install_with_default_version_success(setup_env, packages, mocker):
    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = setup_env["expected"]

    get_package_mock = setup_env["get_package_mock"]
    get_package_mock.configure_mock(
        return_value={
            "conda": {
                "pyspark": Package("pyspark", "pyspark", "0.21", "py_36"),
                "pandas": Package("pandas", "pandas", "0.23", "py_36"),
            }
        })

    mocker.patch("conda_env_tracker.conda.conda_install")

    CondaHandler(env=env).install(packages=packages)

    history = env_io.get_history()

    expected_log = expected["logs"].copy()
    expected_action = expected["actions"].copy()
    expected_packages = copy.deepcopy(expected["packages"])
    package = packages[0]
    expected_packages["conda"]["pyspark"] = package
    expected_log.append(f"conda install --name {env.name} {package.spec}")

    assert history.packages == expected_packages
    channel_string = "--override-channels --strict-channel-priority " + " ".join(
        [f"--channel " + channel for channel in expected["channels"]])
    expected_action.append(
        f"conda install --name {env.name} pyspark=0.21=py_36 {channel_string}")
    assert history.actions == expected_action
    assert history.logs == expected_log
def test_remove_custom_channels(setup_env, channels, mocker):
    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = setup_env["expected"]

    mocker.patch("conda_env_tracker.conda.conda_remove")

    packages = Packages.from_specs("pandas")
    CondaHandler(env=env).remove(packages=packages, channels=channels)

    history = env_io.get_history()
    assert history.channels == expected["channels"]
    assert history.packages == {}
    assert history.logs == expected["logs"] + [
        f"conda remove --name {env.name} pandas "
        + " ".join(["--channel " + channel for channel in channels])
    ]

    computed_channels = channels.copy()
    for channel in expected["channels"]:
        if channel not in computed_channels:
            computed_channels.append(channel)

    remove_channel_string = "--override-channels " + " ".join(
        [f"--channel " + channel for channel in computed_channels]
    )

    assert history.actions == expected["actions"] + [
        f"conda remove --name {env.name} pandas {remove_channel_string}"
    ]
def test_strict_channel_priority_update_all(setup_env, use_package, mocker):
    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = setup_env["expected"]

    get_package_mock = setup_env["get_package_mock"]
    get_package_mock.configure_mock(
        return_value={
            "conda": {
                "pyspark": Package("pyspark", "pyspark", "0.21", "py_36"),
                "pandas": Package("pandas", "pandas", "0.23", "py_36"),
            }
        }
    )

    mocker.patch("conda_env_tracker.conda.conda_update_all")

    expected_packages = copy.deepcopy(expected["packages"])

    update_all_channel_string = "--override-channels " + " ".join(
        f"--channel {channel}" for channel in expected["channels"]
    )

    if use_package:
        CondaHandler(env=env).update_all(
            packages=Packages.from_specs("pyspark"), strict_channel_priority=False
        )
        expected_packages["conda"]["pyspark"] = Package.from_spec("pyspark")
        log = f"conda update --all --name {env.name} pyspark"
        action = f"conda update --all --name {env.name} pyspark=0.21=py_36 {update_all_channel_string}"
    else:
        CondaHandler(env=env).update_all(strict_channel_priority=False)
        log = f"conda update --all --name {env.name}"
        action = f"conda update --all --name {env.name} {update_all_channel_string}"

    history = env_io.get_history()

    expected_logs = expected["logs"].copy()
    expected_logs.append(log)

    expected_actions = expected["actions"].copy()
    expected_actions.append(action)

    assert history.packages == expected_packages
    assert history.actions == expected_actions
    assert history.logs == expected_logs
Exemple #5
0
def conda_remove(
    name: str, specs: ListLike, channels: ListLike = None, yes: bool = False
) -> Environment:
    """Remove conda packages into the environment."""
    env = Environment.read(name=name)
    cleaned = clean_specs(specs)
    CondaHandler(env=env).remove(packages=cleaned, channels=channels, yes=yes)
    _ask_user_to_sync(name=name, yes=yes)
    return env
def test_package_install_with_custom_channel(setup_env, channels, mocker):
    """The user can specify a list of channels that will override the channel precedence order or
    they can specify a custom channel that is not previously in the environment's channel list"""
    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = setup_env["expected"]

    get_package_mock = setup_env["get_package_mock"]
    get_package_mock.configure_mock(
        return_value={
            "conda": {
                "pyspark": Package("pyspark", "pyspark", "0.21", "py_36"),
                "pandas": Package("pandas", "pandas", "0.23", "py_36"),
            }
        }
    )

    mocker.patch("conda_env_tracker.conda.conda_install")

    CondaHandler(env=env).install(
        packages=Packages.from_specs("pyspark"), channels=channels
    )

    history = env_io.get_history()

    expected_log = expected["logs"].copy()
    expected_action = expected["actions"].copy()
    expected_packages = copy.deepcopy(expected["packages"])

    expected_packages["conda"]["pyspark"] = Package.from_spec("pyspark")
    channel_log_string = " ".join(["--channel " + channel for channel in channels])
    expected_log.append(f"conda install --name {env.name} pyspark {channel_log_string}")

    computed_channels = channels.copy()
    for channel in expected["channels"]:
        if not channel in computed_channels:
            computed_channels.append(channel)

    install_channel_string = (
        "--override-channels --strict-channel-priority "
        + " ".join([f"--channel " + channel for channel in computed_channels])
    )

    assert history.packages == expected_packages
    expected_action.append(
        f"conda install --name {env.name} pyspark=0.21=py_36 {install_channel_string}"
    )
    assert history.actions == expected_action
    assert history.logs == expected_log
Exemple #7
0
def _handle_conda_extra_log(env: Environment, history: History,
                            index: int) -> Environment:
    """Handle conda install, conda update --all and conda remove logs."""
    log = history.logs[index]
    channels = history.logs.extract_channels(index=index)
    handler = CondaHandler(env=env)
    if log.startswith("conda remove"):
        packages = history.logs.extra_removed_packages(index=index)
        handler.remove(packages=packages, channels=channels)
    else:
        packages = history.actions.extract_packages(index=index)
        if log.startswith("conda update --all"):
            handler.update_all(packages=packages, channels=channels)
        else:
            handler.install(packages=packages, channels=channels)
    env.history.logs[-1] = log
    return env
def test_install_upgrade_version_success(setup_env, mocker):
    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = setup_env["expected"]

    get_package_mock = setup_env["get_package_mock"]
    get_package_mock.configure_mock(
        return_value={
            "conda": {
                "numpy": Package("numpy", "numpy", "1.1", "py_36"),
                "pandas": Package("pandas", "pandas", "0.24", "py_36"),
            }
        }
    )

    mocker.patch("conda_env_tracker.conda.conda_install")

    packages = Packages.from_specs("numpy")
    CondaHandler(env=env).install(packages=packages)

    history = env_io.get_history()

    channel_string = "--override-channels --strict-channel-priority " + " ".join(
        [f"--channel " + channel for channel in expected["channels"]]
    )
    expected_log = expected["logs"].copy()
    expected_log.append(f"conda install --name {env.name} numpy")

    expected_action = expected["actions"].copy()

    expected_packages = copy.deepcopy(expected["packages"])
    expected_packages["conda"]["numpy"] = Package.from_spec("numpy")
    if expected_packages["conda"]["pandas"].spec_is_name():
        expected_action.append(
            f"conda install --name {env.name} numpy=1.1=py_36 {channel_string}"
        )
    else:
        expected_packages["conda"]["pandas"] = Package.from_spec("pandas=0.24=py_36")
        expected_action.append(
            f"conda install --name {env.name} numpy=1.1=py_36 pandas=0.24=py_36 {channel_string}"
        )

    assert history.packages == expected_packages
    assert history.logs == expected_log
    assert history.actions == expected_action
Exemple #9
0
def update_packages(name: str, specs: ListLike, remove: ListLike) -> Environment:
    """Update the history with local packages installed without cet cli."""
    # pylint: disable=redefined-outer-name
    env = Environment.read(name=name)
    handler = CondaHandler(env=env)
    if remove:
        cleaned_remove = clean_specs(remove)
        handler.update_history_remove(packages=cleaned_remove)
    if specs:
        cleaned = clean_specs(specs)
        handler.update_history_install(packages=cleaned)
    env.export()
    return env
Exemple #10
0
def conda_install(
    name: str,
    specs: ListLike,
    channels: ListLike = None,
    yes: bool = False,
    strict_channel_priority: bool = True,
) -> Environment:
    """Install conda packages into the environment."""
    env = Environment.read(name=name)
    cleaned = process_specs(specs)
    CondaHandler(env=env).install(
        packages=cleaned,
        channels=channels,
        yes=yes,
        strict_channel_priority=strict_channel_priority,
    )
    if not yes:
        jupyter_kernel_install_query(name=name, packages=cleaned)
    _ask_user_to_sync(name=name, yes=yes)
    return env
def test_update_history_conda_remove(setup_env):
    env = setup_env["env"]
    expected = setup_env["expected"]
    channels = expected["channels"]

    packages = Packages.from_specs("pandas")
    CondaHandler(env=env).update_history_remove(packages=packages)

    history = env.history

    log = f"conda remove --name {env.name} pandas"
    action = f"conda remove --name {env.name} pandas --override-channels " + " ".join(
        "--channel " + channel for channel in channels)
    expected_logs = expected["logs"].copy()
    expected_actions = expected["actions"].copy()
    expected_logs.append(log)
    expected_actions.append(action)

    assert history.logs == expected_logs
    assert history.actions == expected_actions
def test_update_all(setup_env, package, mocker):
    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = setup_env["expected"]

    get_package_mock = setup_env["get_package_mock"]
    get_package_mock.configure_mock(return_value={
        "conda": {
            "pandas": Package("pandas", "pandas", "0.24", "py_36")
        }
    })

    mocker.patch("conda_env_tracker.conda.conda_update_all")

    packages = Packages(package)
    CondaHandler(env=env).update_all(packages=packages)

    history = env_io.get_history()

    channel_string = "--override-channels --strict-channel-priority " + " ".join(
        [f"--channel " + channel for channel in expected["channels"]])
    expected_log = expected["logs"].copy()

    expected_log.append(f"conda update --all --name {env.name} {package.spec}")

    action_packages_cmd = " pandas=0.24=py_36"

    expected_action = expected["actions"].copy()
    expected_action.append(
        f"conda update --all --name {env.name}{action_packages_cmd} {channel_string}"
    )

    expected_packages = {
        "conda": {
            "pandas": Package("pandas", package.spec, "0.24", "py_36")
        }
    }

    assert history.packages == expected_packages
    assert history.logs == expected_log
    assert history.actions == expected_action
def test_remove_package(setup_env, mocker):
    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = setup_env["expected"]

    mocker.patch("conda_env_tracker.conda.conda_remove")

    packages = Packages.from_specs("pandas")
    CondaHandler(env=env).remove(packages=packages)

    history = env_io.get_history()
    assert history.channels == expected["channels"]
    assert history.packages == {}
    assert history.logs == expected["logs"] + [f"conda remove --name {env.name} pandas"]
    channel_string = "--override-channels --strict-channel-priority " + " ".join(
        [f"--channel " + channel for channel in expected["channels"]]
    )
    remove_channel_string = channel_string.replace("--strict-channel-priority ", "")
    assert history.actions == expected["actions"] + [
        f"conda remove --name {env.name} pandas {remove_channel_string}"
    ]
def test_remove_dependency(setup_env, mocker):
    """Test removing a dependency 'numpy' which will cause the package 'pandas' to be removed."""
    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = setup_env["expected"]
    logger_mock = mocker.patch("conda_env_tracker.env.logger.warning")

    get_package_mock = setup_env["get_package_mock"]
    get_package_mock.configure_mock(
        return_value={"conda": {"numpy": Package("numpy", "numpy", "1.1", "py_36")}}
    )
    env.dependencies["conda"]["numpy"] = "1.1=py_36"

    mocker.patch("conda_env_tracker.conda.conda_remove")

    packages = Packages.from_specs("numpy")
    CondaHandler(env=env).remove(packages=packages)

    history = env_io.get_history()

    channel_string = "--override-channels --strict-channel-priority " + " ".join(
        [f"--channel " + channel for channel in expected["channels"]]
    )
    remove_channel_string = channel_string.replace("--strict-channel-priority ", "")
    expected_log = expected["logs"].copy()
    expected_log.append(f"conda remove --name {env.name} numpy")

    expected_action = expected["actions"].copy()
    expected_action.append(
        f"conda remove --name {env.name} numpy {remove_channel_string}"
    )

    expected_packages = {}
    assert history.packages == expected_packages
    assert history.logs == expected_log
    assert history.actions == expected_action
    logger_mock.assert_called_once_with(
        'Package "pandas" was removed during the last command.'
    )
def test_install_unexpectedly_removes_package(setup_env, mocker):
    """Simulating that installing python=3.8 uninstalls pandas and
    there is no version of pandas available for python 3.8
    """
    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = setup_env["expected"]
    logger_mock = mocker.patch("conda_env_tracker.env.logger.warning")

    get_package_mock = setup_env["get_package_mock"]
    get_package_mock.configure_mock(
        return_value={"conda": {"python": Package("python", "python", "3.8", "py_38")}}
    )

    mocker.patch("conda_env_tracker.conda.conda_install")

    CondaHandler(env=env).install(packages=Packages.from_specs("python=3.8"))

    history = env_io.get_history()

    channel_string = "--override-channels --strict-channel-priority " + " ".join(
        [f"--channel " + channel for channel in expected["channels"]]
    )
    expected_log = expected["logs"].copy()
    expected_log.append(f"conda install --name {env.name} python=3.8")

    expected_action = expected["actions"].copy()
    expected_action.append(
        f"conda install --name {env.name} python=3.8=py_38 {channel_string}"
    )

    expected_packages = {"conda": {"python": Package.from_spec("python=3.8")}}
    assert history.packages == expected_packages
    assert history.logs == expected_log
    assert history.actions == expected_action
    logger_mock.assert_called_once_with(
        'Package "pandas" was removed during the last command.'
    )
def test_update_all_no_packages(setup_env, mocker):
    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = setup_env["expected"]
    expected_packages = copy.deepcopy(expected["packages"])

    get_package_mock = setup_env["get_package_mock"]
    get_package_mock.configure_mock(return_value={
        "conda": {
            "pandas": Package("pandas", "pandas", "0.24", "py_36")
        }
    })

    mocker.patch("conda_env_tracker.conda.conda_update_all")

    CondaHandler(env=env).update_all()

    history = env_io.get_history()

    channel_string = "--override-channels --strict-channel-priority " + " ".join(
        [f"--channel " + channel for channel in expected["channels"]])
    expected_log = expected["logs"].copy()
    expected_log.append(f"conda update --all --name {env.name}")

    expected_action = expected["actions"].copy()
    expected_action.append(
        f"conda update --all --name {env.name} {channel_string}")

    expected_packages["conda"] = {
        k: Package(v.name, v.name)
        for k, v in expected_packages["conda"].items()
    }

    assert history.packages == expected_packages
    assert history.logs == expected_log
    assert history.actions == expected_action