コード例 #1
0
def test_r_install(setup_env, mocker):
    command = 'install.packages("h2o")'
    escaped_command = command.replace('"', r"\"")
    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = copy.deepcopy(setup_env["expected"])

    run_mock = mocker.patch("conda_env_tracker.gateways.r.run_command")
    run_mock.configure_mock(**{
        "return_value.failed": False,
        "return_value.stderr": ""
    })
    mocker.patch(
        "conda_env_tracker.env.get_r_dependencies",
        mocker.Mock(return_value={"h2o": Package("h2o", "h2o", "3.24.0.3")}),
    )
    h2o = Package("h2o", command)
    packages = Packages([h2o])

    RHandler(env=env).install(packages=packages)
    expected["logs"].append(f'R --quiet --vanilla -e "{escaped_command}"')
    expected["packages"]["r"] = {"h2o": h2o}
    actual = env_io.get_history()

    assert actual.logs == expected["logs"]
    assert actual.packages == expected["packages"]
    assert actual.actions[-1] == expected["logs"][-1]

    actual_install_r = (env_io.env_dir / "install.R").read_text()
    assert actual_install_r == command
コード例 #2
0
ファイル: conda.py プロジェクト: bphillab/conda-env-tracker
def get_dependencies(name: str) -> dict:
    """Get the information about pip and conda packages in the environment using `conda list`.

    Package information includes: name and version
    """
    completed_process = subprocess.run(
        f"conda list --name {name}",
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        shell=True,
        encoding="UTF-8",
    )
    if completed_process.returncode != 0:
        error_message = completed_process.stderr.strip()
        raise CondaEnvTrackerCondaError(error_message)
    lines = completed_process.stdout.strip().split("\n")
    dependencies = {"conda": {}}
    for line in lines:
        if not line.startswith("#"):
            dep = line.strip().split()
            name = dep[0]
            spec = name
            version = dep[1]
            if dep[-1] in ["pip", "pypi"]:
                dependencies["pip"] = dependencies.get("pip", {})
                dependencies["pip"][name] = Package(name, spec, version)
            else:
                build = dep[2]
                dependencies["conda"][name] = Package(name, spec, version,
                                                      build)

    return dependencies
コード例 #3
0
def test_pip_custom_install(setup_env, mocker):
    pip_package_url = "https://s3.amazonaws.com/h2o-release/h2o/master/4765/Python/h2o-3.26.0.4765-py2.py3-none-any.whl"
    pip_dependencies = {"h2o": Package("h2o", pip_package_url)}
    package = Package("h2o", pip_package_url)

    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = copy.deepcopy(setup_env["expected"])
    get_package_mock = setup_env["get_package_mock"]
    initial_conda_packages = setup_env["initial_conda_packages"]

    get_package_mock.configure_mock(**{
        "return_value": {
            "conda": initial_conda_packages,
            "pip": pip_dependencies
        }
    })
    mocker.patch("conda_env_tracker.pip.pip_custom_install")

    PipHandler(env=env).custom_install(package=package)

    install_command = f"pip install {pip_package_url}"
    expected["logs"].append(install_command)
    expected["packages"]["pip"] = pip_dependencies
    action_command = install_command

    actual = env_io.get_history()

    assert actual.logs == expected["logs"]
    assert actual.packages == expected["packages"]
    assert actual.actions[-1] == action_command
コード例 #4
0
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
コード例 #5
0
def test_pip_custom_install_github(setup_env, mocker):
    pip_package_url = "git+ssh://[email protected]/pandas-dev/pandas"
    pip_dependencies = {"pandas": Package("pandas", pip_package_url)}
    package = Package("pandas", pip_package_url)

    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = copy.deepcopy(setup_env["expected"])
    get_package_mock = setup_env["get_package_mock"]
    initial_conda_packages = setup_env["initial_conda_packages"]

    get_package_mock.configure_mock(**{
        "return_value": {
            "conda": initial_conda_packages,
            "pip": pip_dependencies
        }
    })
    mocker.patch("conda_env_tracker.pip.pip_custom_install")

    PipHandler(env=env).custom_install(package=package)

    install_command = f"pip install {pip_package_url}"
    expected["logs"].append(install_command)
    expected["packages"]["pip"] = pip_dependencies
    action_command = install_command

    actual = env_io.get_history()

    assert actual.logs == expected["logs"]
    assert actual.packages == expected["packages"]
    assert actual.actions[-1] == action_command
コード例 #6
0
def test_export_success(mocker):
    """Test package export"""
    mocker.patch(
        "conda_env_tracker.history.history.uuid4").return_value = "unique_uuid"
    expected = {
        "name":
        "environment-name",
        "id":
        "unique_uuid",
        "history-file-version":
        "1.0",
        "channels": ["conda-forge", "main"],
        "packages": {
            "conda": {
                "pytest": "*"
            }
        },
        "revisions": [{
            "log":
            "conda create --name test pytest",
            "action":
            "conda create --name test pytest=4.0=py36_0 "
            "--channel conda-forge "
            "--channel main",
            "debug": {
                "platform": "osx",
                "conda_version": "4.5.10"
            },
            "packages": {
                "conda": {
                    "pytest": "*"
                }
            },
            "diff": {
                "conda": {
                    "upsert": ["pytest=4.0"]
                }
            },
        }],
    }
    actual = History.create(
        name="environment-name",
        channels=Channels(["conda-forge", "main"]),
        packages=PackageRevision(conda=dict(
            pytest=Package.from_spec("pytest"))),
        logs=Logs(["conda create --name test pytest"]),
        actions=Actions([
            "conda create --name test pytest=4.0=py36_0 "
            "--channel conda-forge "
            "--channel main"
        ]),
        diff=Diff(conda=dict(upsert=dict(
            pytest=Package("pytest", version="4.0")))),
        debug=[{
            "platform": "osx",
            "conda_version": "4.5.10"
        }],
    ).export()
    assert expected == actual
コード例 #7
0
def test_ignore_empty_pip_packages(mocker):
    """When a user installs a pip package and then removes it, the pip packages is an empty dictionry which
    does not need to show up in the history file.
    """
    mocker.patch(
        "conda_env_tracker.history.history.uuid4").return_value = "unique_uuid"
    expected = {
        "name":
        "environment-name",
        "id":
        "unique_uuid",
        "history-file-version":
        "1.0",
        "channels": ["main"],
        "packages": {
            "conda": {
                "pytest": "*"
            }
        },
        "revisions": [{
            "log": "conda create --name test pytest",
            "action": "conda create --name test pytest=4.0=py36_0 "
            "--channel main",
            "debug": {
                "platform": "osx",
                "conda_version": "4.5.10"
            },
            "packages": {
                "conda": {
                    "pytest": "*"
                }
            },
            "diff": {
                "conda": {
                    "upsert": ["pytest=4.0"]
                }
            },
        }],
    }
    actual = History.create(
        name="environment-name",
        channels=Channels(["main"]),
        packages=PackageRevision(
            conda=dict(pytest=Package.from_spec("pytest")), pip={}),
        logs=Logs(["conda create --name test pytest"]),
        actions=Actions(
            ["conda create --name test pytest=4.0=py36_0 "
             "--channel main"]),
        diff=Diff(
            dict(conda=dict(upsert=dict(
                pytest=Package("pytest", version="4.0"))))),
        debug=[{
            "platform": "osx",
            "conda_version": "4.5.10"
        }],
    ).export()
    assert expected == actual
コード例 #8
0
def setup(mocker, request):
    """Set up for diff function"""
    local_packages = request.param["local_packages"]
    local_logs = request.param["local_logs"]
    local_actions = request.param["local_actions"]
    env_name = request.param["env_name"]

    remote_packages = request.param["remote_packages"]
    remote_logs = request.param["remote_logs"]
    remote_actions = request.param["remote_actions"]

    dependencies = {
        "conda": {
            "pandas": Package("pandas", "pandas", version="0.23.0"),
            "pytest": Package("pytest", "pytest", version="4.0.0"),
        }
    }
    mocker.patch(
        "conda_env_tracker.env.get_dependencies", mocker.Mock(return_value=dependencies)
    )
    history = History.create(
        name=env_name,
        packages=PackageRevision.create(local_packages, dependencies=dependencies),
        channels=Channels(["conda-forge"]),
        logs=Logs([log for log in local_logs]),
        actions=local_actions,
        diff=Diff(),
        debug=Debug(),
    )
    env = Environment(name=env_name, history=history)
    mocker.patch("conda_env_tracker.main.Environment.read", return_value=env)

    mocker.patch(
        "conda_env_tracker.gateways.io.EnvIO.get_remote_dir",
        return_value="~/path/to/remote",
    )
    mocker.patch("pathlib.Path.is_dir", return_value=True)
    history = History.create(
        name=env_name,
        channels=Channels(["conda-forge"]),
        packages=PackageRevision.create(remote_packages, dependencies=dependencies),
        logs=Logs([log for log in remote_logs]),
        actions=remote_actions,
        diff=Diff(),
        debug=Debug(),
    )
    mocker.patch(
        "conda_env_tracker.gateways.io.EnvIO.get_history", return_value=history
    )
    mocker.patch("pathlib.Path.write_text")

    yield env, request.param["push_should_fail"]

    if (USER_ENVS_DIR / env_name).exists():
        shutil.rmtree(USER_ENVS_DIR / env_name)
コード例 #9
0
def test_export_install_r_multiple():
    custom_command_h2o = 'install.packages("h2o")'
    custom_command_trelliscopejs = (
        'library("devtools"); install_github("hafen/treslliscopejs")'
    )
    packages = {
        "h2o": Package("h2o", custom_command_h2o),
        "trelliscopejs": Package("trelliscopejs", custom_command_trelliscopejs),
    }
    actual = r.export_install_r(packages)
    expected = "\n".join([custom_command_h2o, custom_command_trelliscopejs])
    assert actual == expected
コード例 #10
0
def test_parse_with_package():
    """Test to parse yaml file without any package"""
    history = History.parse({
        "channels": ["conda-forge", "main"],
        "packages": {
            "conda": {
                "pytest": "*"
            }
        },
        "revisions": [{
            "log":
            "conda create --name test pytest",
            "action":
            "conda create --name test pytest=4.0=py36_0 "
            "--channel conda-forge "
            "--channel main",
            "debug": {
                "platform": "linux",
                "conda_version": "4.5.11"
            },
            "packages": {
                "conda": {
                    "pytest": "*"
                }
            },
            "diff": {
                "conda": {
                    "upsert": ["pytest=4.0"]
                }
            },
        }],
    })
    assert ["conda-forge", "main"] == history.channels
    assert {
        "conda": {
            "pytest": Package.from_spec("pytest")
        }
    } == history.packages
    assert ["conda create --name test pytest"] == history.logs
    assert [
        "conda create --name test pytest=4.0=py36_0 "
        "--channel conda-forge "
        "--channel main"
    ] == history.actions
    assert [{"platform": "linux", "conda_version": "4.5.11"}] == history.debug
    assert [{
        "conda": {
            "upsert": {
                "pytest": Package("pytest", "pytest", "4.0")
            }
        }
    }] == history.revisions.diffs
コード例 #11
0
def setup_tests(mocker):
    """Set up for pull function"""
    remote_packages = (Package.from_spec("pandas"),
                       Package.from_spec("pytest"))
    remote_logs = [
        "conda create --name pull_testing_environment pandas",
        "conda install --name pull_testing_environment pytest",
    ]
    remote_actions = [
        "conda create --name pull_testing_environment pandas=0.23=py36",
        "conda install --name pull_testing_environment pytest=0.1=py36_3",
    ]
    remote_history = History(
        name=ENV_NAME,
        channels=CHANNELS,
        packages=HistoryPackages.create(remote_packages),
        logs=Logs([log for log in remote_logs]),
        actions=Actions(remote_actions),
        debug=Debug(),
    )

    mocker.patch("conda_env_tracker.conda.conda_install")
    mocker.patch("conda_env_tracker.conda.conda_update_all")
    mocker.patch("conda_env_tracker.conda.conda_remove")
    mocker.patch("conda_env_tracker.pip.pip_install")
    mocker.patch("conda_env_tracker.pip.pip_remove")
    mocker.patch("conda_env_tracker.history.get_pip_version")
    get_dependencies = mocker.patch("conda_env_tracker.env.get_dependencies")

    overwrite_mock = mocker.patch(
        "conda_env_tracker.pull.EnvIO.overwrite_local")
    mocker.patch("conda_env_tracker.pull.EnvIO.get_remote_dir",
                 return_value="~/path/to/remote")
    mocker.patch("conda_env_tracker.pull.EnvIO.get_history",
                 return_value=remote_history)
    mocker.patch("conda_env_tracker.pull.prompt_yes_no", return_value=True)
    mocker.patch("conda_env_tracker.pull.update_conda_environment")
    mocker.patch("conda_env_tracker.pull.update_r_environment")
    mocker.patch("conda_env_tracker.pull.Environment.export")
    mocker.patch("conda_env_tracker.pull.Environment.validate")
    mocker.patch(
        "conda_env_tracker.pull.Environment.validate_installed_packages")

    yield {
        "get_dependencies": get_dependencies,
        "overwrite_mock": overwrite_mock,
        "remote_history": remote_history,
    }

    env_dir = USER_ENVS_DIR / ENV_NAME
    if env_dir.exists():
        shutil.rmtree(env_dir)
コード例 #12
0
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
コード例 #13
0
def test_write_history_file(env_io):
    """Test to create history yaml file and test get history"""
    env_io.write_history_file(
        History.create(
            name="test-env",
            channels=Channels(["main"]),
            packages=PackageRevision(
                {"conda": {
                    "python": Package.from_spec("python")
                }}),
            logs=Logs(["conda create -n test-env python"]),
            actions=Actions([
                "conda create -n test-env python=3.7.3=buildstring --override-channels --channel main"
            ]),
            diff=Diff({
                "conda": {
                    "upsert": {
                        "python": Package("python", version="3.7.3")
                    }
                }
            }),
            debug=["blah"],
        ))
    assert ["main"] == env_io.get_history().channels
    assert {
        "conda": {
            "python": Package.from_spec("python")
        }
    } == env_io.get_history().packages
    assert (Revisions(
        **{
            "logs": ["conda create -n test-env python"],
            "actions": [
                "conda create -n test-env python=3.7.3=buildstring --override-channels --channel main"
            ],
            "packages": [{
                "conda": {
                    "python": Package.from_spec("python")
                }
            }],
            "diffs": [{
                "conda": {
                    "upsert": {
                        "python": Package("python", "python", version="3.7.3")
                    }
                }
            }],
            "debug": ["blah"],
        }) == env_io.get_history().revisions)
コード例 #14
0
ファイル: test_env.py プロジェクト: quartox/conda-env-tracker
def test_replace_existing_env_success(mocker):
    mocker.patch("conda_env_tracker.env.delete_conda_environment")
    mocker.patch("conda_env_tracker.env.prompt_yes_no").return_value = True
    env_name = "conda_env_tracker-test-create-history"
    create_cmd = f"conda create --name {env_name} pandas"
    channels = ["conda-forge", "main"]
    packages = Packages.from_specs("pandas")
    action = "pandas=0.23=py_36"

    mocker.patch(
        "conda_env_tracker.env.get_all_existing_environment").return_value = [
            env_name
        ]
    mocker.patch("conda_env_tracker.env.conda_create",
                 mocker.Mock(return_value=create_cmd))
    mocker.patch(
        "conda_env_tracker.env.get_dependencies",
        mocker.Mock(return_value={
            "conda": {
                "pandas": Package("pandas", "*", "0.23=py_36")
            },
            "pip": {},
        }),
    )
    mocker.patch(
        "conda_env_tracker.history.debug.get_pip_version",
        mocker.Mock(return_value="18.1"),
    )
    mocker.patch("conda_env_tracker.env.get_conda_channels",
                 mocker.Mock(return_value=channels))
    Environment.create(name=env_name, packages=packages)

    writer = EnvIO(env_directory=USER_ENVS_DIR / env_name)
    history = writer.get_history()
    channel_string = "--override-channels --strict-channel-priority " + " ".join(
        "--channel " + channel for channel in channels)
    assert history.actions == [
        f"conda create --name {env_name} {action} {channel_string}"
    ]
    assert history.packages == {
        "conda": {
            "pandas": Package.from_spec("pandas")
        }
    }
    assert history.channels == channels
    assert history.logs == [create_cmd]

    env_dir = Path(USER_ENVS_DIR) / env_name
    shutil.rmtree(env_dir)
コード例 #15
0
ファイル: test_env.py プロジェクト: quartox/conda-env-tracker
def test_infer_environment_with_pip_package_success(mocker):
    env_name = "infer-test"
    dependencies = {
        "conda": {
            "pandas": Package("pandas", "pandas", "0.23", "py_36")
        },
        "pip": {
            "pytest": Package("pytest", "pytest", "0.11")
        },
    }
    mocker.patch(
        "conda_env_tracker.history.debug.get_pip_version",
        mocker.Mock(return_value="18.1"),
    )
    mocker.patch("conda_env_tracker.env.get_all_existing_environment",
                 return_value=[env_name])
    mocker.patch("conda_env_tracker.env.get_dependencies",
                 mocker.Mock(return_value=dependencies))
    mocker.patch("conda_env_tracker.env.get_r_dependencies")

    env = Environment.infer(
        name=env_name,
        packages=Packages.from_specs(["pandas", "pytest"]),
        channels=["conda-forge", "main"],
    )
    assert env.history.packages == {
        "conda": {
            "pandas": Package("pandas", "pandas", "0.23", "py_36")
        },
        "pip": {
            "pytest": Package("pytest", "pytest", "0.11")
        },
    }
    assert env.history.channels == ["conda-forge", "main"]
    assert env.history.logs == [
        f"conda create --name {env_name} pandas --override-channels --strict-channel-priority "
        "--channel conda-forge "
        "--channel main",
        "pip install pytest --index-url https://pypi.org/simple",
    ]
    assert env.history.actions == [
        f"conda create --name {env_name} pandas=0.23=py_36 "
        "--override-channels --strict-channel-priority "
        "--channel conda-forge "
        "--channel main",
        "pip install pytest==0.11 --index-url"
        " https://pypi.org/simple",
    ]
コード例 #16
0
def test_remove_r_package(setup_env, mocker):
    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = copy.deepcopy(setup_env["expected"])

    r_command = 'install.packages("h2o")'
    run_mock = mocker.patch("conda_env_tracker.gateways.r.run_command")
    run_mock.configure_mock(**{
        "return_value.failed": False,
        "return_value.stderr": ""
    })
    mocker.patch(
        "conda_env_tracker.env.get_r_dependencies",
        mocker.Mock(return_value={"h2o": Package("h2o", "h2o", "3.24.0.3")}),
    )

    handler = RHandler(env=env)
    h2o = Package("h2o", r_command)
    packages = Packages([h2o])
    handler.install(packages=packages)

    install_log = f"R --quiet --vanilla -e '{r_command}'"

    expected["logs"].append(install_log)
    expected["packages"]["r"] = {"h2o": h2o}

    actual = env_io.get_history()

    assert actual.logs == expected["logs"]
    assert actual.packages == expected["packages"]
    assert actual.actions[-1] == install_log

    expected_install_r = r_command
    actual_install_r = (env_io.env_dir / "install.R").read_text()
    assert actual_install_r == expected_install_r

    mocker.patch("conda_env_tracker.r.r_remove")
    handler.remove(packages=packages)
    actual = env_io.get_history()
    command = 'remove.packages(c("h2o"))'

    expected["packages"].pop("r")
    expected["logs"].append(f"R --quiet --vanilla -e '{command}'")
    assert actual.logs == expected["logs"]
    assert actual.packages == expected["packages"]
    assert actual.actions[-1] == expected["logs"][-1]

    assert not (env_io.env_dir / "install.R").exists()
コード例 #17
0
def test_pull_no_new_action_in_local(setup_tests):
    overwrite_mock = setup_tests["overwrite_mock"]
    remote_history = setup_tests["remote_history"]

    local_packages = (Package.from_spec("pandas"), )
    local_logs = ["conda create --name pull_testing_environment pandas"]
    local_actions = [
        "conda create --name pull_testing_environment pandas=0.23=py36"
    ]

    local_history = History(
        name=ENV_NAME,
        packages=HistoryPackages.create(local_packages),
        channels=Channels(),
        logs=Logs([log for log in local_logs]),
        actions=Actions(local_actions),
        debug=Debug(),
    )
    env = Environment(name=ENV_NAME, history=local_history)

    pull(env=env)

    assert env.history.packages == remote_history.packages
    assert env.history.logs == remote_history.logs
    assert env.history.actions == remote_history.actions
    overwrite_mock.called_once()
コード例 #18
0
def test_jupyter_kernel_install_query_user_says_no(mocker):
    run_mock = mocker.patch(
        "conda_env_tracker.gateways.jupyter.subprocess.run")
    run_mock.configure_mock(
        **{
            "return_value.returncode":
            0,
            "return_value.stdout":
            ("Available kernels:\n"
             "  arl             /home/username/.local/share/jupyter/kernels/arl\n"
             "  test-env        /home/username/.local/share/jupyter/kernels/test-env\n"
             "  rasterstats     /home/username/.local/share/jupyter/kernels/rasterstats"
             ),
        })
    mocker.patch(
        "conda_env_tracker.gateways.jupyter.prompt_yes_no",
        new=mocker.Mock(return_value=False),
    )
    debug_mock = mocker.patch(
        "conda_env_tracker.gateways.jupyter.logger.debug")

    jupyter_kernel_install_query(name="myenv",
                                 packages=[Package.from_spec("jupyter")])

    debug_mock.assert_not_called()
    assert len(run_mock.call_args_list) == 1
コード例 #19
0
def test_parse_with_package_with_version():
    """Test to parse yaml file without any package"""
    history = History.parse({
        "name":
        "environment-name",
        "channels": ["conda-forge", "main"],
        "packages": {
            "conda": {
                "pytest": "3.7=py36_0"
            }
        },
        "logs": ["conda create --name test pytest=3.7=py36_0"],
        "actions": ["conda create --name test pytest=3.7=py36_0"],
        "debug": [{
            "platform": "osx",
            "conda_version": "4.5.12"
        }],
    })
    assert history.name == "environment-name"
    assert history.channels == ["conda-forge", "main"]
    assert history.packages == {
        "conda": {
            "pytest": Package.from_spec("pytest=3.7=py36_0")
        }
    }
    assert history.logs == ["conda create --name test pytest=3.7=py36_0"]
    assert history.actions == ["conda create --name test pytest=3.7=py36_0"]
    assert history.debug == [{"platform": "osx", "conda_version": "4.5.12"}]
コード例 #20
0
def test_pip_remove(setup_pip_env, mocker):
    env = setup_pip_env["env"]
    env_io = setup_pip_env["env_io"]

    mocker.patch("conda_env_tracker.pip.pip_remove")
    PipHandler(env=env).remove(packages=Packages.from_specs("pytest"),
                               yes=True)

    actual = env_io.get_history()

    assert actual.logs[-1] == "pip uninstall pytest"
    assert actual.actions[-1] == "pip uninstall pytest"
    assert actual.packages["pip"] == {
        "pandas":
        Package(name="pandas",
                spec="git+ssh://[email protected]/pandas-dev/pandas")
    }

    PipHandler(env=env).remove(packages=Packages.from_specs("pandas"),
                               yes=True)

    actual = env_io.get_history()
    assert actual.logs[-1] == "pip uninstall pandas"
    assert actual.actions[-1] == "pip uninstall pandas"
    assert "pip" not in actual.packages
コード例 #21
0
ファイル: test_env.py プロジェクト: quartox/conda-env-tracker
def test_infer_environment_package_does_not_exist(mocker):
    env_name = "infer-test"
    dependencies = {
        "conda": {
            "pandas": Package("pandas", "pandas", "0.23", "py_36")
        }
    }
    mocker.patch(
        "conda_env_tracker.history.debug.get_pip_version",
        mocker.Mock(return_value="18.1"),
    )
    mocker.patch("conda_env_tracker.env.get_all_existing_environment",
                 return_value=[env_name])
    mocker.patch("conda_env_tracker.env.get_dependencies",
                 mocker.Mock(return_value=dependencies))
    mocker.patch("conda_env_tracker.env.get_r_dependencies")

    with pytest.raises(Exception) as err:
        Environment.infer(
            name=env_name,
            packages=Packages.from_specs("pytest"),
            channels=["conda-forge", "main"],
        )
    assert str(
        err.value) == "Environment infer-test does not have pytest installed"
コード例 #22
0
def test_extract_packages_from_logs(spec):
    """Test parsing the packges from action item"""
    log = Logs(f"conda install --name test {spec}")
    packages = log.extract_packages(index=0,
                                    packages=Packages.from_specs(spec))

    assert packages[0] == Package.from_spec(spec)
コード例 #23
0
ファイル: history.py プロジェクト: bphillab/conda-env-tracker
    def history_diff(env_name: str, env, env_reader) -> ListLike:
        """return the difference between history and local environment"""
        version_diff_pkges: ListLike = []
        new_pkges: ListLike = []
        missing_pkges: ListLike = []

        history_conda_pkges = env_reader.get_environment()["dependencies"]
        history_conda_pkges_dict = {}
        for spec in history_conda_pkges:
            name, package = Package.from_spec(spec)
            history_conda_pkges_dict[name] = package
        local_conda_pkges = get_dependencies(name=env_name)["conda"]
        for name, package in local_conda_pkges.items():
            if name in history_conda_pkges_dict:
                if package.version != history_conda_pkges_dict[name].version:
                    version_diff_pkges.append("-" + name + "=" +
                                              history_conda_pkges_dict[name])
                    version_diff_pkges.append("+" + name + "=" +
                                              package.version)
            else:
                new_pkges.append("+" + name + "=" + package.version)
        for package in env.history.packages["conda"]:
            if package not in local_conda_pkges.keys():
                missing_pkges.append("-" + package)

        return version_diff_pkges, new_pkges, missing_pkges
コード例 #24
0
def test_two_same_package_r_install(setup_env, mocker):
    """Test that the second command replaces the first command (and updates the version of the package)"""
    command_h2o_1 = 'install.packages("h2o")'
    escaped_command_1 = command_h2o_1.replace('"', r"\"")
    command_h2o_2 = 'install.packages("h2o", type="source", repos=(c("http://h2o-release.s3.amazonaws.com/h2o/latest_stable_R")))'
    escaped_command_2 = command_h2o_2.replace('"', r"\"")
    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = copy.deepcopy(setup_env["expected"])

    run_mock = mocker.patch("conda_env_tracker.gateways.r.run_command")
    run_mock.configure_mock(**{
        "return_value.failed": False,
        "return_value.stderr": ""
    })
    mocker.patch(
        "conda_env_tracker.env.get_r_dependencies",
        side_effect=[
            {
                "h2o": Package("h2o", "h2o", "3.4.0.1")
            },
            {
                "h2o": Package("h2o", "h2o", "3.24.0.5")
            },
        ],
    )

    h2o_1 = Package("h2o", command_h2o_1)
    h2o_2 = Package("h2o", command_h2o_2)

    packages_1 = Packages([h2o_1])
    packages_2 = Packages([h2o_2])

    RHandler(env=env).install(packages=packages_1)
    RHandler(env=env).install(packages=packages_2)

    expected["logs"].append(f'R --quiet --vanilla -e "{escaped_command_1}"')
    expected["logs"].append(f'R --quiet --vanilla -e "{escaped_command_2}"')
    expected["packages"]["r"] = {"h2o": h2o_2}
    actual = env_io.get_history()

    assert actual.logs == expected["logs"]
    assert actual.packages == expected["packages"]
    assert actual.actions[-1] == expected["logs"][-1]

    actual_install_r = (env_io.env_dir / "install.R").read_text()
    assert actual_install_r == command_h2o_2
コード例 #25
0
ファイル: pip.py プロジェクト: bphillab/conda-env-tracker
def get_pip_version(name: str) -> Optional[str]:
    """Check for the version of pip (if installed)."""
    if is_current_conda_env(name):
        import pip

        return pip.__version__
    dependencies = get_dependencies(name=name)
    return dependencies["conda"].get("pip", Package(name="pip")).version
コード例 #26
0
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
コード例 #27
0
def test_export_install_r_single_package():
    packages = Packages(
        Package(
            "jsonlite",
            'library("devtools"); install_version("jsonlite",version="1.6")'))
    actual = r.export_install_r(packages)
    expected = 'library("devtools"); install_version("jsonlite",version="1.6")'
    assert actual == expected
コード例 #28
0
def test_export_install_r_multiple_installs():
    packages = Packages([
        Package(
            "jsonlite",
            'library("devtools"); install_version("jsonlite",version="1.6")',
        ),
        Package(
            "praise",
            'library("devtools"); install_version("praise",version="1.0.0")',
        ),
    ])
    actual = r.export_install_r(packages)
    expected = "\n".join([
        'library("devtools"); install_version("jsonlite",version="1.6")',
        'library("devtools"); install_version("praise",version="1.0.0")',
    ])
    assert actual == expected
コード例 #29
0
def test_jupyter_kernel_install_query_jupyter_not_in_packages(mocker):
    run_mock = mocker.patch(
        "conda_env_tracker.gateways.jupyter.subprocess.run")

    jupyter_kernel_install_query(name="myenv",
                                 packages=[Package.from_spec("numpy")])

    run_mock.assert_not_called()
コード例 #30
0
def test_pull_different_actions_in_both_r(setup_r_tests):
    remote_history = setup_r_tests["remote_history"]
    get_r_dependencies = setup_r_tests["get_r_dependencies"]
    get_r_dependencies.configure_mock(
        **{
            "return_value": {
                "praise": Package("praise", "praise", "1.0.0"),
                "jsonlite": Package("jsonlite", "jsonlite", "1.6"),
            }
        })

    local_history = copy.deepcopy(remote_history)

    local_history.packages.update_packages(packages=Packages(
        Package("praise", 'install.packages("praise")')),
                                           source="r")
    local_history.logs.append(f"{R_COMMAND} -e 'install.packages(\"praise\")'")
    local_history.actions.append(
        f"{R_COMMAND} -e 'install.packages(\"praise\")'")

    env = Environment(name=local_history.name, history=local_history)

    remote_history.packages.update_packages(
        packages=Packages(Package("jsonlite", 'install.packages("jsonlite")')),
        source="r",
    )
    remote_history.logs.append(
        f"{R_COMMAND} -e 'install.packages(\"jsonlite\")'")
    remote_history.actions.append(
        f"{R_COMMAND} -e 'install.packages(\"jsonlite\")'")

    expected_history = copy.deepcopy(remote_history)

    expected_history.packages.update_packages(packages=Packages(
        Package("praise", 'install.packages("praise")')),
                                              source="r")
    expected_history.logs.append(
        f"{R_COMMAND} -e 'install.packages(\"praise\")'")
    expected_history.actions.append(
        f"{R_COMMAND} -e 'install.packages(\"praise\")'")

    final_env = pull(env=env)

    assert final_env.history.packages == expected_history.packages
    assert final_env.history.logs == expected_history.logs
    assert final_env.history.actions == expected_history.actions