Skip to content

Commit

Permalink
Fix auto pip deps (#30)
Browse files Browse the repository at this point in the history
* Fix bug that prevented file writing, bump version

* Fix bug where pip wasn't properly being added. Simplify env_deps in
manifest class

* Add function for writing yaml, add test for same

* Bump version
  • Loading branch information
tylerpotts authored Nov 17, 2021
1 parent 79dbd7c commit 9db0938
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 74 deletions.
5 changes: 2 additions & 3 deletions conda_vendor/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
yaml_from_manifest,
)
from conda_vendor.version import __version__
from conda_vendor.manifest import combine_metamanifests
from conda_vendor.manifest import combine_metamanifests, write_combined_manifest
import yaml
import logging

Expand Down Expand Up @@ -97,8 +97,7 @@ def combine_manifests(verbose, meta_manifest_paths, output_combined_path):
combined_manifest = combine_metamanifests(manifest_paths=paths)

logger.info(f"Writing combined manifest to: {output_combined_path}")
with open(output_combined_path, "w") as f:
yaml.dump(combined_manifest, f, sort_keys=False)
write_combined_manifest(output_combined_path, combined_manifest)


@click.command(help="local channels from meta-manifest file")
Expand Down
1 change: 0 additions & 1 deletion conda_vendor/conda_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ def get_platform_from_manifest(self):
def get_all_repo_data(self):
if self.all_repo_data:
return self.all_repo_data
# this is where
all_repo_data = {}

for chan in self.channels:
Expand Down
108 changes: 55 additions & 53 deletions conda_vendor/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,52 +17,6 @@
logger = logging.getLogger(__name__)


def combine_metamanifests(manifest_paths):
manifests = read_manifests(manifest_paths)

combined = {}
for manifest in manifests:
for channel in manifest.keys():
if not channel in combined.keys():
combined[channel] = manifest[channel]
else:
for arch in manifest[channel].keys():
if arch in combined[channel].keys():
pkg_list = deduplicate_pkg_list(
combined[channel][arch]["entries"]
+ manifest[channel][arch]["entries"]
)
combined[channel][arch]["entries"] = pkg_list
else:
combined[channel][arch]["entries"] = manifest[channel][arch][
"entries"
]
combined[channel][arch]["repodata_url"] = manifest[channel][
arch
]["repodata_url"]
return combined


def deduplicate_pkg_list(package_list):
seen_shas = set()
deduped_list = []

for package in package_list:
if package["sha256"] not in seen_shas:
deduped_list.append(package)
seen_shas.add(package["sha256"])

return deduped_list


def read_manifests(manifest_paths):
manifest_list = []
for manifest_path in manifest_paths:
with open(manifest_path, "r") as f:
manifest_list.append(yaml.safe_load(f))
return manifest_list


class LockWrapper:
@staticmethod
def parse(*args):
Expand Down Expand Up @@ -118,13 +72,9 @@ def __init__(
}

logger.info(f"Using Environment :{environment_yml}")
with open(environment_yml) as f:
self.env_deps["environment"] = yaml.load(f, Loader=yaml.SafeLoader)
bad_channels = ["nodefaults"]
self.channels = [
chan
for chan in self.env_deps["environment"]["channels"]
if chan not in bad_channels
chan for chan in self.env_deps["channels"] if chan not in bad_channels
]
if "defaults" in self.channels:
raise RuntimeError("default channels are not supported.")
Expand All @@ -145,11 +95,12 @@ def add_pip_question_mark(self):

def add_pip_dependency(self):
add_pip_dependency = self.add_pip_question_mark()
dependencies = self.env_deps["environment"]["dependencies"].copy()

dependencies = self.env_deps["specs"].copy()
has_python = "python" in "".join(dependencies)

if add_pip_dependency is True and has_python:
self.env_deps["environment"]["dependencies"].append("pip")
self.env_deps["specs"].append("pip")

def get_manifest_filename(self, manifest_filename=None):
if manifest_filename is None:
Expand Down Expand Up @@ -219,3 +170,54 @@ def solve_environment(self):

logger.debug(f'Fetch results: {self.env_deps["solution"]["actions"]["FETCH"]}')
return self.env_deps["solution"]["actions"]["FETCH"]


def combine_metamanifests(manifest_paths):
manifests = read_manifests(manifest_paths)

combined = {}
for manifest in manifests:
for channel in manifest.keys():
if not channel in combined.keys():
combined[channel] = manifest[channel]
else:
for arch in manifest[channel].keys():
if arch in combined[channel].keys():
pkg_list = deduplicate_pkg_list(
combined[channel][arch]["entries"]
+ manifest[channel][arch]["entries"]
)
combined[channel][arch]["entries"] = pkg_list
else:
combined[channel][arch]["entries"] = manifest[channel][arch][
"entries"
]
combined[channel][arch]["repodata_url"] = manifest[channel][
arch
]["repodata_url"]
return combined


def deduplicate_pkg_list(package_list):
seen_shas = set()
deduped_list = []

for package in package_list:
if package["sha256"] not in seen_shas:
deduped_list.append(package)
seen_shas.add(package["sha256"])

return deduped_list


def read_manifests(manifest_paths):
manifest_list = []
for manifest_path in manifest_paths:
with open(manifest_path, "r") as f:
manifest_list.append(yaml.safe_load(f))
return manifest_list


def write_combined_manifest(manifest_path, combined_manifest):
with open(manifest_path, "w") as f:
yaml.dump(combined_manifest, f, sort_keys=False)
3 changes: 2 additions & 1 deletion conda_vendor/version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
__version__ = "0.1.13"
__version__ = "0.1.14"


if __name__ == "__main__":
print(__version__, end="")
37 changes: 21 additions & 16 deletions tests/test_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
combine_metamanifests,
deduplicate_pkg_list,
read_manifests,
write_combined_manifest,
)
import pytest
from requests import Response
Expand Down Expand Up @@ -56,13 +57,8 @@ def test_MetaManifest_init(minimal_environment, tmp_path):
expected_manifest = None
expected_type = MetaManifest
expected_env_deps = {
"specs": ["python=3.9.5"],
"specs": ["python=3.9.5", "pip"],
"channels": ["main"],
"environment": {
"name": "minimal_env",
"channels": ["main"],
"dependencies": ["python=3.9.5", "pip"],
},
}

assert test_meta_manifest.platform is not None
Expand Down Expand Up @@ -90,7 +86,7 @@ def test_MetaManifest_solve_environment(mock, meta_manifest_fixture):
mock.assert_called_with(
"conda",
["main", "conda-forge"],
specs=["python=3.9.5", "conda-mirror=0.8.2"],
specs=["python=3.9.5", "conda-mirror=0.8.2", "pip"],
platform=platform,
)
TestCase().assertDictEqual(result[0], expected[0])
Expand Down Expand Up @@ -254,19 +250,17 @@ def test_add_pip_question_mark(meta_manifest_fixture):

def test_add_pip_dependency(meta_manifest_fixture):
mock_env_python = {
"name": "blah",
"channels": ["chronotrigger"],
"dependencies": ["python"],
"specs": ["python"],
}

expected_env = {
"name": "blah",
"channels": ["chronotrigger"],
"dependencies": ["python", "pip"],
"specs": ["python", "pip"],
}
meta_manifest_fixture.env_deps["environment"] = mock_env_python
meta_manifest_fixture.env_deps = mock_env_python
meta_manifest_fixture.add_pip_dependency()
result = meta_manifest_fixture.env_deps["environment"]
result = meta_manifest_fixture.env_deps

TestCase().assertDictEqual(result, expected_env)

Expand Down Expand Up @@ -353,14 +347,13 @@ def test_combine_metamanifests(tmp_path):
with open(manifest_path_2, "w") as f:
yaml.dump(test_manifest2, f)


actual_return = combine_metamanifests(test_manifests_list)
assert actual_return == expected_return


def test_read_manifests(tmp_path):
yaml1 = {"key1", "value1"}
yaml2 = {"key2", "value2"}
yaml1 = {"key1": "value1"}
yaml2 = {"key2": "value2"}

yaml_path1 = tmp_path / "yaml1.yaml"
yaml_path2 = tmp_path / "yaml2.yaml"
Expand All @@ -375,3 +368,15 @@ def test_read_manifests(tmp_path):
actual_manifest_list = read_manifests([yaml_path1, yaml_path2])

assert actual_manifest_list == expected_manifest_list


def test_write_combined_manifest(tmp_path):
test_yaml = {"key1": "value1"}
yaml_path = tmp_path / "test_yaml.yaml"

write_combined_manifest(yaml_path, test_yaml)

with open(yaml_path, "r") as f:
actual_yaml = yaml.safe_load(f)

TestCase().assertDictEqual(actual_yaml, test_yaml)

0 comments on commit 9db0938

Please sign in to comment.