def remove_actions(prefix, specs, index, force=False, pinned=True): r = Resolve(index) linked = [d+'.tar.bz2' for d in install.linked(prefix)] mss = list(map(MatchSpec, specs)) if force: nlinked = {r.package_name(fn):fn[:-8] for fn in linked if not any(r.match(ms, fn) for ms in mss)} else: if config.track_features: specs.extend(x + '@' for x in config.track_features) nlinked = {r.package_name(fn):fn[:-8] for fn in r.remove(specs, linked)} if pinned: pinned_specs = get_pinned_specs(prefix) log.debug("Pinned specs=%s" % pinned_specs) linked = {r.package_name(fn):fn[:-8] for fn in linked} actions = ensure_linked_actions(r.dependency_sort(nlinked), prefix) for old_fn in reversed(r.dependency_sort(linked)): dist = old_fn + '.tar.bz2' name = r.package_name(dist) if old_fn == nlinked.get(name,''): continue if pinned and any(r.match(ms, dist) for ms in pinned_specs): raise RuntimeError( "Cannot remove %s because it is pinned. Use --no-pin to override." % dist) if name == 'conda' and name not in nlinked: if any(ms.name == 'conda' for ms in mss): sys.exit("Error: 'conda' cannot be removed from the root environment") else: sys.exit("Error: this 'remove' command cannot be executed because it\nwould require removing 'conda' dependencies.") add_unlink(actions, old_fn) return actions
def install_actions(prefix, index, specs, force=False, only_names=None, always_copy=False, pinned=True, minimal_hint=False, update_deps=True, prune=False): r = Resolve(index) linked = r.installed if config.self_update and is_root_prefix(prefix): specs.append('conda') if pinned: pinned_specs = get_pinned_specs(prefix) log.debug("Pinned specs=%s" % pinned_specs) specs += pinned_specs must_have = {} if config.track_features: specs.extend(x + '@' for x in config.track_features) pkgs = r.install(specs, linked, update_deps=update_deps) for fn in pkgs: dist = fn[:-8] name = install.name_dist(dist) if not name or only_names and name not in only_names: continue must_have[name] = dist if is_root_prefix(prefix): for name in config.foreign: if name in must_have: del must_have[name] elif basename(prefix).startswith('_'): # anything (including conda) can be installed into environments # starting with '_', mainly to allow conda-build to build conda pass else: # disallow conda from being installed into all other environments if 'conda' in must_have or 'conda-env' in must_have: sys.exit("Error: 'conda' can only be installed into the " "root environment") smh = r.dependency_sort(must_have) actions = ensure_linked_actions( smh, prefix, index=index if force else None, force=force, always_copy=always_copy) if actions[inst.LINK]: actions[inst.SYMLINK_CONDA] = [config.root_dir] for fkey in sorted(linked): dist = fkey[:-8] name = install.name_dist(dist) replace_existing = name in must_have and dist != must_have[name] prune_it = prune and dist not in smh if replace_existing or prune_it: add_unlink(actions, dist) return actions
def install_actions(prefix, index, specs, force=False, only_names=None, always_copy=False, pinned=True, minimal_hint=False, update_deps=True, prune=False): r = Resolve(index) linked = r.installed if self_update and is_root_prefix(prefix): specs.append('conda') if pinned: pinned_specs = get_pinned_specs(prefix) log.debug("Pinned specs=%s" % pinned_specs) specs += pinned_specs must_have = {} if track_features: specs.extend(x + '@' for x in track_features) pkgs = r.install(specs, linked, update_deps=update_deps) for fn in pkgs: dist = fn[:-8] name = install.name_dist(dist) if not name or only_names and name not in only_names: continue must_have[name] = dist if is_root_prefix(prefix): for name in foreign: if name in must_have: del must_have[name] elif basename(prefix).startswith('_'): # anything (including conda) can be installed into environments # starting with '_', mainly to allow conda-build to build conda pass else: # disallow conda from being installed into all other environments if 'conda' in must_have or 'conda-env' in must_have: sys.exit("Error: 'conda' can only be installed into the " "root environment") smh = r.dependency_sort(must_have) actions = ensure_linked_actions( smh, prefix, index=index if force else None, force=force, always_copy=always_copy) if actions[inst.LINK]: actions[inst.SYMLINK_CONDA] = [root_dir] for fkey in sorted(linked): dist = fkey[:-8] name = install.name_dist(dist) replace_existing = name in must_have and dist != must_have[name] prune_it = prune and dist not in smh if replace_existing or prune_it: add_unlink(actions, dist) return actions
def remove_actions(prefix, specs, index, force=False, pinned=True): r = Resolve(index) linked = [d + '.tar.bz2' for d in install.linked(prefix)] mss = list(map(MatchSpec, specs)) if force: nlinked = { r.package_name(fn): fn[:-8] for fn in linked if not any(r.match(ms, fn) for ms in mss) } else: if config.track_features: specs.extend(x + '@' for x in config.track_features) nlinked = { r.package_name(fn): fn[:-8] for fn in r.remove(specs, linked) } if pinned: pinned_specs = get_pinned_specs(prefix) log.debug("Pinned specs=%s" % pinned_specs) linked = {r.package_name(fn): fn[:-8] for fn in linked} actions = ensure_linked_actions(r.dependency_sort(nlinked), prefix) for old_fn in reversed(r.dependency_sort(linked)): dist = old_fn + '.tar.bz2' name = r.package_name(dist) if old_fn == nlinked.get(name, ''): continue if pinned and any(r.match(ms, dist) for ms in pinned_specs): raise RuntimeError( "Cannot remove %s because it is pinned. Use --no-pin to override." % dist) if name == 'conda' and name not in nlinked: if any(ms.name == 'conda' for ms in mss): sys.exit( "Error: 'conda' cannot be removed from the root environment" ) else: sys.exit( "Error: this 'remove' command cannot be executed because it\nwould require removing 'conda' dependencies." ) add_unlink(actions, old_fn) return actions
def install_actions(prefix, index, specs, force=False, only_names=None, pinned=True, minimal_hint=False, update_deps=True): r = Resolve(index) linked = install.linked(prefix) if config.self_update and is_root_prefix(prefix): specs.append('conda') if pinned: pinned_specs = get_pinned_specs(prefix) log.debug("Pinned specs=%s" % pinned_specs) specs += pinned_specs # TODO: Improve error messages here add_defaults_to_specs(r, linked, specs) must_have = {} if config.track_features: specs.extend(x + '@' for x in config.track_features) pkgs = r.install(specs, [d + '.tar.bz2' for d in linked], update_deps=update_deps) for fn in pkgs: dist = fn[:-8] name = install.name_dist(dist) if not name or only_names and name not in only_names: continue must_have[name] = dist if is_root_prefix(prefix): for name in config.foreign: if name in must_have: del must_have[name] elif basename(prefix).startswith('_'): # anything (including conda) can be installed into environments # starting with '_', mainly to allow conda-build to build conda pass else: # disallow conda from being installed into all other environments if 'conda' in must_have or 'conda-env' in must_have: sys.exit("Error: 'conda' can only be installed into the " "root environment") smh = r.dependency_sort(must_have) if force: actions = force_linked_actions(smh, index, prefix) else: actions = ensure_linked_actions(smh, prefix) if actions[inst.LINK] and sys.platform != 'win32' and prefix != config.root_dir: actions[inst.SYMLINK_CONDA] = [config.root_dir] for dist in sorted(linked): name = install.name_dist(dist) if name in must_have and dist != must_have[name]: add_unlink(actions, dist) return actions
def remove_actions(prefix, specs, index, force=False, pinned=True): r = Resolve(index) linked = r.installed if force: mss = list(map(MatchSpec, specs)) nlinked = { r.package_name(fn): fn[:-8] for fn in linked if not any(r.match(ms, fn) for ms in mss) } else: add_defaults_to_specs(r, linked, specs, update=True) nlinked = { r.package_name(fn): fn[:-8] for fn in r.remove(specs, linked) } if pinned: pinned_specs = get_pinned_specs(prefix) log.debug("Pinned specs=%s" % pinned_specs) linked = {r.package_name(fn): fn[:-8] for fn in linked} actions = ensure_linked_actions(r.dependency_sort(nlinked), prefix) for old_fn in reversed(r.dependency_sort(linked)): dist = old_fn + '.tar.bz2' name = r.package_name(dist) if old_fn == nlinked.get(name, ''): continue if pinned and any(r.match(ms, dist) for ms in pinned_specs): msg = "Cannot remove %s becaue it is pinned. Use --no-pin to override." raise RuntimeError(msg % dist) if name == 'conda' and name not in nlinked: if any(s.split(' ', 1)[0] == 'conda' for s in specs): sys.exit( "Error: 'conda' cannot be removed from the root environment" ) else: msg = ( "Error: this 'remove' command cannot be executed because it\n" "would require removing 'conda' dependencies") sys.exit(msg) add_unlink(actions, old_fn) return actions
def remove_actions(prefix, specs, index, force=False, pinned=True): r = Resolve(index) linked = r.installed if force: mss = list(map(MatchSpec, specs)) nlinked = {r.package_name(fn): fn[:-8] for fn in linked if not any(r.match(ms, fn) for ms in mss)} else: add_defaults_to_specs(r, linked, specs, update=True) nlinked = {r.package_name(fn): fn[:-8] for fn in r.remove(specs, linked)} if pinned: pinned_specs = get_pinned_specs(prefix) log.debug("Pinned specs=%s" % pinned_specs) linked = {r.package_name(fn): fn[:-8] for fn in linked} actions = ensure_linked_actions(r.dependency_sort(nlinked), prefix) for old_fn in reversed(r.dependency_sort(linked)): dist = old_fn + '.tar.bz2' name = r.package_name(dist) if old_fn == nlinked.get(name, ''): continue if pinned and any(r.match(ms, dist) for ms in pinned_specs): msg = "Cannot remove %s becaue it is pinned. Use --no-pin to override." raise RuntimeError(msg % dist) if name == 'conda' and name not in nlinked: if any(s.split(' ', 1)[0] == 'conda' for s in specs): sys.exit("Error: 'conda' cannot be removed from the root environment") else: msg = ("Error: this 'remove' command cannot be executed because it\n" "would require removing 'conda' dependencies") sys.exit(msg) add_unlink(actions, old_fn) return actions
def clone_env(prefix1, prefix2, verbose=True, quiet=False, index=None): """ clone existing prefix1 into new prefix2 """ untracked_files = untracked(prefix1) dists = discard_conda(install.linked(prefix1)) if verbose: print('Packages: %d' % len(dists)) print('Files: %d' % len(untracked_files)) for f in untracked_files: src = join(prefix1, f) dst = join(prefix2, f) dst_dir = dirname(dst) if islink(dst_dir) or isfile(dst_dir): os.unlink(dst_dir) if not isdir(dst_dir): os.makedirs(dst_dir) if islink(src): os.symlink(os.readlink(src), dst) continue try: with open(src, 'rb') as fi: data = fi.read() except IOError: continue try: s = data.decode('utf-8') s = s.replace(prefix1, prefix2) data = s.encode('utf-8') except UnicodeDecodeError: # data is binary pass with open(dst, 'wb') as fo: fo.write(data) shutil.copystat(src, dst) if index is None: index = get_index() r = Resolve(index) sorted_dists = r.dependency_sort(dists) actions = ensure_linked_actions(sorted_dists, prefix2) execute_actions(actions, index=index, verbose=not quiet) return actions, untracked_files
def clone_env(prefix1, prefix2, verbose=True, quiet=False, fetch_args=None): """ clone existing prefix1 into new prefix2 """ untracked_files = untracked(prefix1) # Discard conda and any package that depends on it drecs = install.linked_data(prefix1) filter = {} found = True while found: found = False for dist, info in iteritems(drecs): name = info['name'] if name in filter: continue if name == 'conda': filter['conda'] = dist found = True break for dep in info.get('depends', []): if MatchSpec(dep).name in filter: filter[name] = dist found = True if not quiet and filter: print('The following packages cannot be cloned out of the root environment:') for pkg in itervalues(filter): print(' - ' + pkg) # Assemble the URL and channel list urls = {} index = {} for dist, info in iteritems(drecs): if info['name'] in filter: continue url = info.get('url') if url is None: sys.exit('Error: no URL found for package: %s' % dist) _, schannel = url_channel(url) index[dist + '.tar.bz2'] = info urls[dist] = url r = Resolve(index) dists = r.dependency_sort(urls.keys()) urls = [urls[d] for d in dists] if verbose: print('Packages: %d' % len(dists)) print('Files: %d' % len(untracked_files)) for f in untracked_files: src = join(prefix1, f) dst = join(prefix2, f) dst_dir = dirname(dst) if islink(dst_dir) or isfile(dst_dir): os.unlink(dst_dir) if not isdir(dst_dir): os.makedirs(dst_dir) if islink(src): os.symlink(os.readlink(src), dst) continue try: with open(src, 'rb') as fi: data = fi.read() except IOError: continue try: s = data.decode('utf-8') s = s.replace(prefix1, prefix2) data = s.encode('utf-8') except UnicodeDecodeError: # data is binary pass with open(dst, 'wb') as fo: fo.write(data) shutil.copystat(src, dst) actions = explicit(urls, prefix2, verbose=not quiet, force_extract=False, fetch_args=fetch_args) return actions, untracked_files
def clone_env(prefix1, prefix2, verbose=True, quiet=False, fetch_args=None): """ clone existing prefix1 into new prefix2 """ untracked_files = untracked(prefix1) # Discard conda and any package that depends on it drecs = install.linked_data(prefix1) filter = {} found = True while found: found = False for dist, info in iteritems(drecs): name = info['name'] if name in filter: continue if name == 'conda': filter['conda'] = dist found = True break for dep in info.get('depends', []): if MatchSpec(dep).name in filter: filter[name] = dist found = True if not quiet and filter: print( 'The following packages cannot be cloned out of the root environment:' ) for pkg in itervalues(filter): print(' - ' + pkg) # Assemble the URL and channel list urls = {} index = {} for dist, info in iteritems(drecs): if info['name'] in filter: continue url = info.get('url') if url is None: sys.exit('Error: no URL found for package: %s' % dist) _, schannel = url_channel(url) index[dist + '.tar.bz2'] = info urls[dist] = url r = Resolve(index) dists = r.dependency_sort(urls.keys()) urls = [urls[d] for d in dists] if verbose: print('Packages: %d' % len(dists)) print('Files: %d' % len(untracked_files)) for f in untracked_files: src = join(prefix1, f) dst = join(prefix2, f) dst_dir = dirname(dst) if islink(dst_dir) or isfile(dst_dir): os.unlink(dst_dir) if not isdir(dst_dir): os.makedirs(dst_dir) if islink(src): os.symlink(os.readlink(src), dst) continue try: with open(src, 'rb') as fi: data = fi.read() except IOError: continue try: s = data.decode('utf-8') s = s.replace(prefix1, prefix2) data = s.encode('utf-8') except UnicodeDecodeError: # data is binary pass with open(dst, 'wb') as fo: fo.write(data) shutil.copystat(src, dst) actions = explicit(urls, prefix2, verbose=not quiet, force_extract=False, fetch_args=fetch_args) return actions, untracked_files
def install_actions(prefix, index, specs, force=False, only_names=None, pinned=True, minimal_hint=False, update_deps=True): r = Resolve(index) linked = install.linked(prefix) if config.self_update and is_root_prefix(prefix): specs.append('conda') if pinned: pinned_specs = get_pinned_specs(prefix) log.debug("Pinned specs=%s" % pinned_specs) specs += pinned_specs # TODO: Improve error messages here add_defaults_to_specs(r, linked, specs) must_have = {} if config.track_features: specs.extend(x + '@' for x in config.track_features) for fn in r.install(specs, [d + '.tar.bz2' for d in linked], update_deps=update_deps): dist = fn[:-8] name = install.name_dist(dist) if only_names and name not in only_names: continue must_have[name] = dist if is_root_prefix(prefix): for name in config.foreign: if name in must_have: del must_have[name] elif basename(prefix).startswith('_'): # anything (including conda) can be installed into environments # starting with '_', mainly to allow conda-build to build conda pass else: # disallow conda from being installed into all other environments if 'conda' in must_have or 'conda-env' in must_have: sys.exit("Error: 'conda' can only be installed into the " "root environment") smh = r.dependency_sort(must_have) if force: actions = force_linked_actions(smh, index, prefix) else: actions = ensure_linked_actions(smh, prefix) if actions[inst. LINK] and sys.platform != 'win32' and prefix != config.root_dir: actions[inst.SYMLINK_CONDA] = [config.root_dir] for dist in sorted(linked): name = install.name_dist(dist) if name in must_have and dist != must_have[name]: add_unlink(actions, dist) return actions
def create_rpmbuild_for_tag(repo, tag_name, target, config, api_user=None, api_key=None): try: # Python3... from urllib.parse import urlparse except ImportError: # Python2... from urlparse import urlparse rpm_prefix = config['rpm']['prefix'] print("CREATE FOR {}".format(tag_name)) tag = repo.tags[tag_name] # Checkout the tag in a detached head form. repo.head.reference = tag.commit repo.head.reset(working_tree=True) manifest_fname = os.path.join(repo.working_dir, 'env.manifest') if not os.path.exists(manifest_fname): emsg = "The tag '{}' doesn't have a manifested environment." raise ValueError(emsg.format(tag_name)) with open(manifest_fname, 'r') as fh: manifest = sorted(line.strip().split('\t') for line in fh) if api_user and api_key: # Inject the API user and key into the channel URLs... for i, (url, _) in enumerate(manifest): parts = urlparse(url) api_url = '{}://{}:{}@{}{}'.format(parts.scheme, api_user, api_key, parts.netloc, parts.path) manifest[i][0] = api_url create_rpmbuild_for_env(manifest, target, config) index = conda.fetch.fetch_index(list(set([url for url, _ in manifest])), use_cache=False) resolver = Resolve(index) # To sort, the distributions must match the format of the keys of the index # For example, most will look like `http://channel::pkg # However channels on anaconda go by their name rather than their url, # i.e. `conda-forge::pkg` dists = [] for url, pkg in manifest: anaconda_url = 'https://conda.anaconda.org/' if url.startswith(anaconda_url): url = url[len(anaconda_url):] dists.append('::'.join([os.path.dirname(url), pkg])) sorted_dists = resolver.dependency_sort(dists) sorted_pkgs = [dist.split('::')[-1] for dist in sorted_dists] spec_fname = os.path.join(repo.working_dir, 'env.spec') if not os.path.exists(spec_fname): emsg = "The tag '{}' doesn't have an environment specification." raise ValueError(emsg.format(tag_name)) with open(spec_fname, 'r') as fh: env_spec = yaml.safe_load(fh).get('env', []) env_name, tag = tag_name.split('-', 2)[1:] fname = '{}-env-{}-tag-{}.spec'.format(rpm_prefix, env_name, tag) with open(os.path.join(target, 'SPECS', fname), 'w') as fh: fh.write( generate.render_taggedenv(env_name, tag, sorted_pkgs, config, env_spec))