Esempio n. 1
0
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
Esempio n. 2
0
File: plan.py Progetto: brentp/conda
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
Esempio n. 3
0
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
Esempio n. 4
0
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
Esempio n. 5
0
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
Esempio n. 6
0
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
Esempio n. 7
0
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
Esempio n. 8
0
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
Esempio n. 9
0
File: misc.py Progetto: megies/conda
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
Esempio n. 10
0
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
Esempio n. 11
0
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
Esempio n. 12
0
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))