def test_channel(self): d = Dist.from_string("conda-forge::spyder-app-2.3.8-py27_0.tar.bz2") assert d.channel == 'conda-forge' assert d.quad[0] == "spyder-app" assert d.dist_name == "spyder-app-2.3.8-py27_0" d = Dist.from_string("s3://some/bucket/name::spyder-app-2.3.8-py27_0.tar.bz2") assert d.channel == 's3://some/bucket/name' assert d.quad[0] == "spyder-app" assert d.dist_name == "spyder-app-2.3.8-py27_0"
def test_channel(self): d = Dist.from_string("conda-forge::spyder-app-2.3.8-py27_0.tar.bz2") assert d.channel == 'conda-forge' assert d.quad[0] == "spyder-app" assert d.dist_name == "spyder-app-2.3.8-py27_0" d = Dist.from_string( "s3://some/bucket/name::spyder-app-2.3.8-py27_0.tar.bz2") assert d.channel == 's3://some/bucket/name' assert d.quad[0] == "spyder-app" assert d.dist_name == "spyder-app-2.3.8-py27_0"
def test_channel(fmt): d = Dist.from_string("conda-forge::spyder-app-2.3.8-py27_0{}".format(fmt)) assert d.channel == 'conda-forge' assert d.quad[0] == "spyder-app" assert d.dist_name == "spyder-app-2.3.8-py27_0" assert d.fmt == fmt d = Dist.from_string("s3://some/bucket/name::spyder-app-2.3.8-py27_0{}".format(fmt)) assert d.channel == 's3://some/bucket/name' assert d.quad[0] == "spyder-app" assert d.dist_name == "spyder-app-2.3.8-py27_0" assert d.to_url() == join_url("s3://some/bucket/name", context.subdir, "spyder-app-2.3.8-py27_0{}".format(fmt))
def setUp(self): self.index = { Dist.from_string("test1-1", channel_override="defaults"): generate_mocked_package(None, "test1", "default", "1.0.1"), Dist.from_string("test1-1", channel_override="rando_chnl"): generate_mocked_package("env", "test1", "default", "2.1.4"), Dist.from_string("test2-2", channel_override="defaults"): generate_mocked_package("env", "test2", "default", "1.1.1"), Dist.from_string("test3-3", channel_override="defaults"): generate_mocked_package(None, "test3", "default", "1.2.0"), Dist.from_string("test4-4", channel_override="defaults"): generate_mocked_package(None, "test4", "default", "1.2.1") } self.res = generate_mocked_resolve(None, self.index)
def test_simply_adds_unlink_on_non_windows(self): actions = {} dist = Dist.from_string(self.generate_random_dist()) with self.mock_platform(windows=False): plan.add_unlink(actions, dist) self.assertIn(inst.UNLINK, actions) self.assertEqual(actions[inst.UNLINK], [dist, ])
def test_dist(self): d = Dist.from_string("spyder-app-2.3.8-py27_0.tar.bz2") assert d.channel == UNKNOWN_CHANNEL assert d.quad[0] == "spyder-app" assert d.quad[1] == "2.3.8" assert d.quad[2] == "py27_0" assert d.build_number == 0 assert d.dist_name == "spyder-app-2.3.8-py27_0" assert d == Dist.from_string("spyder-app-2.3.8-py27_0") assert d != Dist.from_string("spyder-app-2.3.8-py27_1.tar.bz2") d2 = Dist("spyder-app-2.3.8-py27_0.tar.bz2") assert d == d2 d3 = Dist(d2) assert d3 is d2
def conda_lock(specification: schema.CondaSpecification, conda_exe: str = "mamba"): from conda_lock.conda_lock import run_lock from conda.models.dist import Dist with tempfile.TemporaryDirectory() as tmpdir: environment_path = pathlib.Path(tmpdir) / "environment.yaml" lockfile_path = pathlib.Path(tmpdir) / "environment-lock.yaml" with environment_path.open("w") as f: f.write(specification.json()) try: run_lock( environment_files=[environment_path], platforms=[conda_platform()], lockfile_path=lockfile_path, conda_exe=conda_exe, ) except subprocess.CalledProcessError as e: raise ValueError(e.output) with lockfile_path.open() as f: lockfile = yaml.safe_load(f) conda_packages = [] pip_packages = [] for package in lockfile["package"]: if package["manager"] == "conda": dist = Dist.from_string(package["url"]) conda_packages.append({ "name": dist.name, "build": dist.build, "build_number": dist.build_number, "constrains": None, "depends": [], "license": None, "license_family": None, "size": -1, "subdir": dist.subdir, "timestamp": None, "version": dist.version, "channel_id": dist.base_url, "md5": package["hash"].get("md5"), "sha256": package["hash"].get("sha256", ""), "summary": None, "description": None, }) elif package["manager"] == "pip": pip_packages.append({ "name": package["name"], "url": package["url"], "version": package["version"], "sha256": package["hash"]["sha256"], }) return {"conda": conda_packages, "pip": pip_packages}
def test_dist(fmt): d = Dist.from_string("spyder-app-2.3.8-py27_0{}".format(fmt)) assert d.channel == UNKNOWN_CHANNEL assert d.quad[0] == "spyder-app" assert d.quad[1] == "2.3.8" assert d.quad[2] == "py27_0" assert d.build_number == 0 assert d.dist_name == "spyder-app-2.3.8-py27_0" assert d.fmt == fmt assert d == Dist.from_string("spyder-app-2.3.8-py27_0") assert d != Dist.from_string("spyder-app-2.3.8-py27_1{}".format(fmt)) d2 = Dist("spyder-app-2.3.8-py27_0{}".format(fmt)) assert d == d2 d3 = Dist(d2) assert d3 is d2
def setUp(self): pkgs = { "test-spec": [generate_mocked_package("test1", "test-spec", "defaults", "1"), generate_mocked_package(None, "test-spec", "defaults", "3"), generate_mocked_package(None, "test-spec", "defaults", "2"), generate_mocked_package("ranenv", "test-spec", "rando_chnl", "5")], "test-spec2": [generate_mocked_package(None, "test-spec2", "defaults", "1")], "no-exist": [generate_mocked_package(None, "no-exist", "nope", "1")] } index = { Dist.from_string("test-spec", channel_override="defaults"): generate_mocked_package(None, "test-spec", "default", "1"), Dist.from_string("test-spec", channel_override="rando_chnl"): generate_mocked_package("ranenv", "test-spec", "default", "5"), Dist.from_string("test-spec2", channel_override="defaults"): generate_mocked_package("test1", "test-spec2", "default", "1") } self.res = generate_mocked_resolve(pkgs, index) self.specs = [MatchSpec("test-spec"), MatchSpec("test-spec2")]
def test_with_feature_depends(self): d = Dist.from_string("spyder-app-2.3.8-py27_0[mkl]") assert d.with_features_depends == "mkl" d = Dist("mkl@") assert d.channel == "@" assert d.quad[0] == "mkl@" assert d.quad[1] == "" assert d.quad[2] == "" assert d.with_features_depends is None assert d.is_feature_package
def generate_mocked_resolve(pkgs, install=None): mock_package = namedtuple( "IndexRecord", ["preferred_env", "name", "schannel", "version", "fn"]) mock_resolve = namedtuple("Resolve", [ "get_dists_for_spec", "index", "explicit", "install", "package_name", "dependency_sort" ]) index = {} groups = defaultdict(list) for preferred_env, name, schannel, version in pkgs: dist = Dist.from_string('%s-%s-0' % (name, version), channel_override=schannel) pkg = mock_package(preferred_env=preferred_env, name=name, schannel=schannel, version=version, fn=name) groups[name].append(dist) index[dist] = pkg def get_dists_for_spec(spec, emptyok=False): # Here, spec should be a MatchSpec res = groups[spec.name] if not res and not emptyok: raise NoPackagesFoundError([(spec, )]) return res def get_explicit(spec): return True def get_install(spec, installed, update_deps=None): return install def get_package_name(dist): return dist.name def get_dependency_sort(specs): return tuple(spec for spec in specs.values()) return mock_resolve(get_dists_for_spec=get_dists_for_spec, index=index, explicit=get_explicit, install=get_install, package_name=get_package_name, dependency_sort=get_dependency_sort)
def create_env(repo, pkgs, target): with Locked(target): spec_fname = os.path.join(repo.working_dir, 'env.spec') with open(spec_fname, 'r') as fh: spec = yaml.safe_load(fh) channels = prioritize_channels(spec.get('channels', [])) # Build reverse look-up from channel URL to channel name. channel_by_url = {url: channel for url, (channel, _) in channels.items()} index = fetch_index(channels, use_cache=False) resolver = Resolve(index) # Create the package distribution from the manifest. Ensure to replace # channel-URLs with channel names, otherwise the fetch-extract may fail. dists = [Dist.from_string(pkg, channel_override=channel_by_url.get(url, url)) for url, pkg in pkgs] # Use the resolver to sort packages into the appropriate dependency # order. sorted_dists = resolver.dependency_sort({dist.name: dist for dist in dists}) pfe = ProgressiveFetchExtract(index, sorted_dists) pfe.execute() mkdir_p(target) txn = UnlinkLinkTransaction.create_from_dists(index, target, (), sorted_dists) txn.execute()
def generate_mocked_resolve(pkgs, install=None): mock_package = namedtuple("IndexRecord", ["preferred_env", "name", "schannel", "version", "fn"]) mock_resolve = namedtuple("Resolve", ["get_dists_for_spec", "index", "explicit", "install", "package_name", "dependency_sort"]) index = {} groups = defaultdict(list) for preferred_env, name, schannel, version in pkgs: dist = Dist.from_string('%s-%s-0' % (name, version), channel_override=schannel) pkg = mock_package(preferred_env=preferred_env, name=name, schannel=schannel, version=version, fn=name) groups[name].append(dist) index[dist] = pkg def get_dists_for_spec(spec, emptyok=False): # Here, spec should be a MatchSpec res = groups[spec.name] if not res and not emptyok: raise NoPackagesFoundError([(spec,)]) return res def get_explicit(spec): return True def get_install(spec, installed, update_deps=None): return install def get_package_name(dist): return dist.name def get_dependency_sort(specs): return tuple(spec for spec in specs.values()) return mock_resolve(get_dists_for_spec=get_dists_for_spec, index=index, explicit=get_explicit, install=get_install, package_name=get_package_name, dependency_sort=get_dependency_sort)
def solve(specs): return [Dist.from_string(fn) for fn in r.solve(specs)]
def test_display_actions_0(): os.environ['CONDA_SHOW_CHANNEL_URLS'] = 'False' reset_context(()) actions = defaultdict( list, {"FETCH": [Dist('sympy-0.7.2-py27_0'), Dist("numpy-1.7.1-py27_0")]}) # The older test index doesn't have the size metadata d = Dist.from_string('sympy-0.7.2-py27_0.tar.bz2') index[d] = IndexRecord.from_objects(index[d], size=4374752) d = Dist.from_string("numpy-1.7.1-py27_0.tar.bz2") index[d] = IndexRecord.from_objects(index[d], size=5994338) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be downloaded: package | build ---------------------------|----------------- sympy-0.7.2 | py27_0 4.2 MB numpy-1.7.1 | py27_0 5.7 MB ------------------------------------------------------------ Total: 9.9 MB """ actions = defaultdict( list, { 'PREFIX': '/Users/aaronmeurer/anaconda/envs/test', 'SYMLINK_CONDA': ['/Users/aaronmeurer/anaconda'], 'LINK': [ 'python-3.3.2-0', 'readline-6.2-0 1', 'sqlite-3.7.13-0 1', 'tk-8.5.13-0 1', 'zlib-1.2.7-0 1' ] }) with captured() as c: display_actions(actions, index) assert c.stdout == """Package plan for environment '/Users/aaronmeurer/anaconda/envs/test': The following NEW packages will be INSTALLED: python: 3.3.2-0 \n\ readline: 6.2-0 \n\ sqlite: 3.7.13-0 tk: 8.5.13-0 zlib: 1.2.7-0 \n\ """ actions['UNLINK'] = actions['LINK'] actions['LINK'] = [] with captured() as c: display_actions(actions, index) assert c.stdout == """Package plan for environment '/Users/aaronmeurer/anaconda/envs/test': The following packages will be REMOVED: python: 3.3.2-0 \n\ readline: 6.2-0 \n\ sqlite: 3.7.13-0 tk: 8.5.13-0 zlib: 1.2.7-0 \n\ """ actions = defaultdict(list, { 'LINK': ['cython-0.19.1-py33_0'], 'UNLINK': ['cython-0.19-py33_0'] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be UPDATED: cython: 0.19-py33_0 --> 0.19.1-py33_0 """ actions['LINK'], actions['UNLINK'] = actions['UNLINK'], actions['LINK'] with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be DOWNGRADED: cython: 0.19.1-py33_0 --> 0.19-py33_0 """ actions = defaultdict( list, { 'LINK': [ 'cython-0.19.1-py33_0', 'dateutil-1.5-py33_0', 'numpy-1.7.1-py33_0' ], 'UNLINK': ['cython-0.19-py33_0', 'dateutil-2.1-py33_1', 'pip-1.3.1-py33_1'] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following NEW packages will be INSTALLED: numpy: 1.7.1-py33_0 The following packages will be REMOVED: pip: 1.3.1-py33_1 The following packages will be UPDATED: cython: 0.19-py33_0 --> 0.19.1-py33_0 The following packages will be DOWNGRADED: dateutil: 2.1-py33_1 --> 1.5-py33_0 \n\ """ actions = defaultdict( list, { 'LINK': ['cython-0.19.1-py33_0', 'dateutil-2.1-py33_1'], 'UNLINK': ['cython-0.19-py33_0', 'dateutil-1.5-py33_0'] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be UPDATED: cython: 0.19-py33_0 --> 0.19.1-py33_0 dateutil: 1.5-py33_0 --> 2.1-py33_1 \n\ """ actions['LINK'], actions['UNLINK'] = actions['UNLINK'], actions['LINK'] with captured() as c: display_actions(actions, index) assert c.stdout == """
def test_adds_to_existing_actions(self): actions = {inst.UNLINK: [{"foo": "bar"}]} dist = Dist.from_string(self.generate_random_dist()) with self.mock_platform(windows=False): plan.add_unlink(actions, dist) self.assertEqual(2, len(actions[inst.UNLINK]))
def _ensure_dist_or_dict(fn): try: from conda.models.dist import Dist return Dist.from_string(fn) except ImportError: return fn
def test_display_actions(): os.environ["CONDA_SHOW_CHANNEL_URLS"] = "False" reset_context(()) actions = defaultdict(list, {"FETCH": [Dist("sympy-0.7.2-py27_0"), Dist("numpy-1.7.1-py27_0")]}) # The older test index doesn't have the size metadata index[Dist.from_string("sympy-0.7.2-py27_0.tar.bz2")]["size"] = 4374752 index[Dist.from_string("numpy-1.7.1-py27_0.tar.bz2")]["size"] = 5994338 with captured() as c: display_actions(actions, index) assert ( c.stdout == """ The following packages will be downloaded: package | build ---------------------------|----------------- sympy-0.7.2 | py27_0 4.2 MB numpy-1.7.1 | py27_0 5.7 MB ------------------------------------------------------------ Total: 9.9 MB """ ) actions = defaultdict( list, { "PREFIX": "/Users/aaronmeurer/anaconda/envs/test", "SYMLINK_CONDA": ["/Users/aaronmeurer/anaconda"], "LINK": ["python-3.3.2-0", "readline-6.2-0 1", "sqlite-3.7.13-0 1", "tk-8.5.13-0 1", "zlib-1.2.7-0 1"], }, ) with captured() as c: display_actions(actions, index) assert ( c.stdout == """ The following NEW packages will be INSTALLED: python: 3.3.2-0 \n\ readline: 6.2-0 \n\ sqlite: 3.7.13-0 tk: 8.5.13-0 zlib: 1.2.7-0 \n\ """ ) actions["UNLINK"] = actions["LINK"] actions["LINK"] = [] with captured() as c: display_actions(actions, index) assert ( c.stdout == """ The following packages will be REMOVED: python: 3.3.2-0 \n\ readline: 6.2-0 \n\ sqlite: 3.7.13-0 tk: 8.5.13-0 zlib: 1.2.7-0 \n\ """ ) actions = defaultdict(list, {"LINK": ["cython-0.19.1-py33_0"], "UNLINK": ["cython-0.19-py33_0"]}) with captured() as c: display_actions(actions, index) assert ( c.stdout == """ The following packages will be UPDATED: cython: 0.19-py33_0 --> 0.19.1-py33_0 """ ) actions["LINK"], actions["UNLINK"] = actions["UNLINK"], actions["LINK"] with captured() as c: display_actions(actions, index) assert ( c.stdout == """ The following packages will be DOWNGRADED due to dependency conflicts: cython: 0.19.1-py33_0 --> 0.19-py33_0 """ ) actions = defaultdict( list, { "LINK": ["cython-0.19.1-py33_0", "dateutil-1.5-py33_0", "numpy-1.7.1-py33_0"], "UNLINK": ["cython-0.19-py33_0", "dateutil-2.1-py33_1", "pip-1.3.1-py33_1"], }, ) with captured() as c: display_actions(actions, index) assert ( c.stdout == """ The following NEW packages will be INSTALLED: numpy: 1.7.1-py33_0 The following packages will be REMOVED: pip: 1.3.1-py33_1 The following packages will be UPDATED: cython: 0.19-py33_0 --> 0.19.1-py33_0 The following packages will be DOWNGRADED due to dependency conflicts: dateutil: 2.1-py33_1 --> 1.5-py33_0 \n\ """ ) actions = defaultdict( list, { "LINK": ["cython-0.19.1-py33_0", "dateutil-2.1-py33_1"], "UNLINK": ["cython-0.19-py33_0", "dateutil-1.5-py33_0"], }, ) with captured() as c: display_actions(actions, index) assert ( c.stdout == """ The following packages will be UPDATED: cython: 0.19-py33_0 --> 0.19.1-py33_0 dateutil: 1.5-py33_0 --> 2.1-py33_1 \n\ """ ) actions["LINK"], actions["UNLINK"] = actions["UNLINK"], actions["LINK"] with captured() as c: display_actions(actions, index) assert ( c.stdout == """ The following packages will be DOWNGRADED due to dependency conflicts: cython: 0.19.1-py33_0 --> 0.19-py33_0 dateutil: 2.1-py33_1 --> 1.5-py33_0 \n\ """ )
def test_display_actions(): os.environ['CONDA_SHOW_CHANNEL_URLS'] = 'False' reset_context(()) actions = defaultdict(list, {"FETCH": [Dist('sympy-0.7.2-py27_0'), Dist("numpy-1.7.1-py27_0")]}) # The older test index doesn't have the size metadata d = Dist.from_string('sympy-0.7.2-py27_0.tar.bz2') index[d] = IndexRecord.from_objects(index[d], size=4374752) d = Dist.from_string("numpy-1.7.1-py27_0.tar.bz2") index[d] = IndexRecord.from_objects(index[d], size=5994338) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be downloaded: package | build ---------------------------|----------------- sympy-0.7.2 | py27_0 4.2 MB numpy-1.7.1 | py27_0 5.7 MB ------------------------------------------------------------ Total: 9.9 MB """ actions = defaultdict(list, {'PREFIX': '/Users/aaronmeurer/anaconda/envs/test', 'SYMLINK_CONDA': ['/Users/aaronmeurer/anaconda'], 'LINK': ['python-3.3.2-0', 'readline-6.2-0 1', 'sqlite-3.7.13-0 1', 'tk-8.5.13-0 1', 'zlib-1.2.7-0 1']}) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following NEW packages will be INSTALLED: python: 3.3.2-0 \n\ readline: 6.2-0 \n\ sqlite: 3.7.13-0 tk: 8.5.13-0 zlib: 1.2.7-0 \n\ """ actions['UNLINK'] = actions['LINK'] actions['LINK'] = [] with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be REMOVED: python: 3.3.2-0 \n\ readline: 6.2-0 \n\ sqlite: 3.7.13-0 tk: 8.5.13-0 zlib: 1.2.7-0 \n\ """ actions = defaultdict(list, {'LINK': ['cython-0.19.1-py33_0'], 'UNLINK': ['cython-0.19-py33_0']}) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be UPDATED: cython: 0.19-py33_0 --> 0.19.1-py33_0 """ actions['LINK'], actions['UNLINK'] = actions['UNLINK'], actions['LINK'] with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be DOWNGRADED due to dependency conflicts: cython: 0.19.1-py33_0 --> 0.19-py33_0 """ actions = defaultdict(list, {'LINK': ['cython-0.19.1-py33_0', 'dateutil-1.5-py33_0', 'numpy-1.7.1-py33_0'], 'UNLINK': ['cython-0.19-py33_0', 'dateutil-2.1-py33_1', 'pip-1.3.1-py33_1']}) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following NEW packages will be INSTALLED: numpy: 1.7.1-py33_0 The following packages will be REMOVED: pip: 1.3.1-py33_1 The following packages will be UPDATED: cython: 0.19-py33_0 --> 0.19.1-py33_0 The following packages will be DOWNGRADED due to dependency conflicts: dateutil: 2.1-py33_1 --> 1.5-py33_0 \n\ """ actions = defaultdict(list, {'LINK': ['cython-0.19.1-py33_0', 'dateutil-2.1-py33_1'], 'UNLINK': ['cython-0.19-py33_0', 'dateutil-1.5-py33_0']}) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be UPDATED: cython: 0.19-py33_0 --> 0.19.1-py33_0 dateutil: 1.5-py33_0 --> 2.1-py33_1 \n\ """ actions['LINK'], actions['UNLINK'] = actions['UNLINK'], actions['LINK'] with captured() as c: display_actions(actions, index) assert c.stdout == """
def ensure_dist_or_dict(fn): return _Dist.from_string(fn)