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, 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 = {} for fn in r.solve(specs, [d + '.tar.bz2' for d in linked], config.track_features, minimal_hint=minimal_hint, 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): if install.on_win: for name in install.win_ignore_root: if name in must_have: del must_have[name] 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: sys.exit("Error: 'conda' can only be installed into the " "root environment") smh = r.graph_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 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 install_actions(prefix, index, specs, force=False, only_names=None, pinned=True, minimal_hint=False): r = Resolve(index) linked = install.linked(prefix) if config.self_update and is_root_prefix(prefix): specs.append('conda') add_defaults_to_specs(r, linked, specs) if pinned: pinned_specs = get_pinned_specs(prefix) specs += pinned_specs # TODO: Improve error messages here must_have = {} for fn in r.solve(specs, [d + '.tar.bz2' for d in linked], config.track_features, minimal_hint=minimal_hint): 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): if install.on_win: for name in install.win_ignore_root: if name in must_have: del must_have[name] for name in config.foreign: if name in must_have: del must_have[name] else: # discard conda from other environments if 'conda' in must_have: sys.exit("Error: 'conda' can only be installed into " "root environment") smh = r.graph_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': 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]: actions[inst.UNLINK].append(dist) return actions
def install_actions(prefix, index, specs, force=False, only_names=None, pinned=True, minimal_hint=False): 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 = {} for fn in r.solve(specs, [d + '.tar.bz2' for d in linked], config.track_features, minimal_hint=minimal_hint): 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): if install.on_win: for name in install.win_ignore_root: if name in must_have: del must_have[name] 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: sys.exit("Error: 'conda' can only be installed into the " "root environment") smh = r.graph_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 install_actions(prefix, index, specs, force=False, only_names=None, pinned=True, minimal_hint=False): r = Resolve(index) linked = install.linked(prefix) if config.self_update and is_root_prefix(prefix): specs.append('conda') add_defaults_to_specs(r, linked, specs) if pinned: pinned_specs = get_pinned_specs(prefix) specs += pinned_specs # TODO: Improve error messages here must_have = {} for fn in r.solve(specs, [d + '.tar.bz2' for d in linked], config.track_features, minimal_hint=minimal_hint): 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): if install.on_win: for name in install.win_ignore_root: if name in must_have: del must_have[name] for name in config.foreign: if name in must_have: del must_have[name] else: # discard conda from other environments if 'conda' in must_have: sys.exit("Error: 'conda' can only be installed into " "root environment") smh = r.graph_sort(must_have) if force: actions = force_linked_actions(smh, index, prefix) else: actions = ensure_linked_actions(smh, prefix) if actions[LINK] and sys.platform != 'win32': actions[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]: actions[UNLINK].append(dist) return actions
def force_extract_and_link(dists, prefix, verbose=False): actions = defaultdict(list) actions['PREFIX'] = prefix actions['op_order'] = RM_EXTRACTED, EXTRACT, UNLINK, LINK # maps names of installed packages to dists linked = {install.name_dist(dist): dist for dist in install.linked(prefix)} for dist in dists: actions[RM_EXTRACTED].append(dist) actions[EXTRACT].append(dist) # unlink any installed package with that name name = install.name_dist(dist) if name in linked: actions[UNLINK].append(linked[name]) actions[LINK].append(dist) execute_actions(actions, verbose=verbose)
def add_defaults_to_specs(r, linked, specs, update=False): # TODO: This should use the pinning mechanism. But don't change the API: # cas uses it. if r.explicit(specs): return log.debug('H0 specs=%r' % specs) names_linked = {install.name_dist(dist): dist for dist in linked} names_ms = {MatchSpec(s).name: MatchSpec(s) for s in specs} for name, def_ver in [('python', default_python), # Default version required, but only used for Python ('lua', None)]: ms = names_ms.get(name) if ms and not ms.is_simple(): # if any of the specifications mention the Python/Numpy version, # we don't need to add the default spec log.debug('H1 %s' % name) continue any_depends_on = any(ms2.name == name for spec in specs for fn in r.find_matches(spec) for ms2 in r.ms_depends(fn)) log.debug('H2 %s %s' % (name, any_depends_on)) if not any_depends_on and name not in names_ms: # if nothing depends on Python/Numpy AND the Python/Numpy is not # specified, we don't need to add the default spec log.debug('H2A %s' % name) continue if (any_depends_on and len(specs) >= 1 and MatchSpec(specs[0]).is_exact()): # if something depends on Python/Numpy, but the spec is very # explicit, we also don't need to add the default spec log.debug('H2B %s' % name) continue if name in names_linked: # if Python/Numpy is already linked, we add that instead of the # default log.debug('H3 %s' % name) fkey = names_linked[name] + '.tar.bz2' info = r.index[fkey] ver = '.'.join(info['version'].split('.', 2)[:2]) spec = '%s %s*' % (info['name'], ver) if update: spec += ' (target=%s)' % fkey specs.append(spec) continue if (name, def_ver) in [('python', '3.3'), ('python', '3.4'), ('python', '3.5')]: # Don't include Python 3 in the specs if this is the Python 3 # version of conda. continue specs.append('%s %s*' % (name, def_ver)) log.debug('HF specs=%r' % specs)
def install_actions(prefix, index, specs, force=False, only_names=None): r = Resolve(index) linked = install.linked(prefix) if is_root_prefix(prefix): specs.append('conda') add_defaults_to_specs(r, linked, specs) must_have = {} for fn in r.solve(specs, [d + '.tar.bz2' for d in linked], config.track_features): 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): if not (force or only_names or r.explicit(specs)): # ensure conda is in root environment assert 'conda' in must_have if install.on_win: for name in install.win_ignore_root: if name in must_have: del must_have[name] for name in config.foreign: if name in must_have: del must_have[name] else: # discard conda from other environments if 'conda' in must_have: sys.exit("Error: 'conda' can only be installed into " "root environment") smh = sorted(must_have.values()) if force: actions = force_linked_actions(smh, index, prefix) else: actions = ensure_linked_actions(smh, prefix) for dist in sorted(linked): name = install.name_dist(dist) if name in must_have and dist != must_have[name]: actions[UNLINK].append(dist) return actions
def get_packages(installed, regex): pat = re.compile(regex, re.I) if regex else None for dist in sorted(installed, key=str.lower): name = install.name_dist(dist) if pat and pat.search(name) is None: continue yield dist
def add_defaults_to_specs(r, linked, specs, update=False): # TODO: This should use the pinning mechanism. But don't change the API: # cas uses it. if r.explicit(specs): return log.debug('H0 specs=%r' % specs) names_linked = {install.name_dist(dist): dist for dist in linked} names_ms = {MatchSpec(s).name: MatchSpec(s) for s in specs} for name, def_ver in [ ('python', config.default_python), # Default version required, but only used for Python ('lua', None) ]: ms = names_ms.get(name) if ms and ms.strictness > 1: # if any of the specifications mention the Python/Numpy version, # we don't need to add the default spec log.debug('H1 %s' % name) continue any_depends_on = any(ms2.name == name for spec in specs for fn in r.find_matches(spec) for ms2 in r.ms_depends(fn)) log.debug('H2 %s %s' % (name, any_depends_on)) if not any_depends_on and name not in names_ms: # if nothing depends on Python/Numpy AND the Python/Numpy is not # specified, we don't need to add the default spec log.debug('H2A %s' % name) continue if (any_depends_on and len(specs) >= 1 and MatchSpec(specs[0]).strictness == 3): # if something depends on Python/Numpy, but the spec is very # explicit, we also don't need to add the default spec log.debug('H2B %s' % name) continue if name in names_linked: # if Python/Numpy is already linked, we add that instead of the # default log.debug('H3 %s' % name) spec = dist2spec3v(names_linked[name]) if update: spec = '%s (target=%s.tar.bz2)' % (spec, names_linked[name]) specs.append(spec) continue if (name, def_ver) in [('python', '3.3'), ('python', '3.4'), ('python', '3.5')]: # Don't include Python 3 in the specs if this is the Python 3 # version of conda. continue specs.append('%s %s*' % (name, def_ver)) log.debug('HF specs=%r' % specs)
def install_actions(prefix, index, specs, force=False, only_names=None): r = Resolve(index) linked = install.linked(prefix) if is_root_prefix(prefix): specs.append("conda") add_defaults_to_specs(r, linked, specs) must_have = {} for fn in r.solve(specs, [d + ".tar.bz2" for d in linked]): 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): if not (force or only_names): # ensure conda is in root environment assert "conda" in must_have if install.on_win: for name in install.win_ignore_root: if name in must_have: del must_have[name] else: # discard conda from other environments if "conda" in must_have: del must_have["conda"] smh = sorted(must_have.values()) if force: actions = force_linked_actions(smh, index, prefix) else: actions = ensure_linked_actions(smh, prefix) for dist in sorted(linked): name = install.name_dist(dist) if name in must_have and dist != must_have[name]: actions[UNLINK].append(dist) return actions
def test_dist2quad(): assert dist2quad('python-2.7.11-0') == ('python', '2.7.11', '0', 'defaults') assert dist2quad('python-2.7.11-0.tar.bz2') == ('python', '2.7.11', '0', 'defaults') assert dist2quad('test::python-2.7.11-0') == ('python', '2.7.11', '0', 'test') assert dist2quad('test::python-2.7.11-0.tar.bz2') == ('python', '2.7.11', '0', 'test') assert dist2quad('python-test-2.7.11-0') == ('python-test', '2.7.11', '0', 'defaults') assert _dist2pair('python-2.7.11-0') == ('defaults', 'python-2.7.11-0') assert _dist2pair('python-2.7.11-0.tar.bz2') == ('defaults', 'python-2.7.11-0') assert _dist2pair('test::python-2.7.11-0') == ('test', 'python-2.7.11-0') assert _dist2pair('test::python-2.7.11-0.tar.bz2') == ('test', 'python-2.7.11-0') assert _dist2pair('python-test-2.7.11-0') == ('defaults', 'python-test-2.7.11-0') assert _dist2filename('python-2.7.11-0') == 'python-2.7.11-0.tar.bz2' assert _dist2filename('python-2.7.11-0.tar.bz2') == 'python-2.7.11-0.tar.bz2' assert _dist2filename('test::python-2.7.11-0') == 'python-2.7.11-0.tar.bz2' assert _dist2filename('test::python-2.7.11-0.tar.bz2') == 'python-2.7.11-0.tar.bz2' assert _dist2filename('python-test-2.7.11-0') == 'python-test-2.7.11-0.tar.bz2' assert name_dist('python-2.7.11-0') == 'python' assert name_dist('python-2.7.11-0.tar.bz2') == 'python' assert name_dist('test::python-2.7.11-0') == 'python' assert name_dist('test::python-2.7.11-0.tar.bz2') == 'python' assert name_dist('python-test-2.7.11-0') == 'python-test'
def add_defaults_to_specs(r, linked, specs): # TODO: This should use the pinning mechanism. But don't change the API: # cas uses it. if r.explicit(specs): return log.debug('H0 specs=%r' % specs) names_linked = {install.name_dist(dist): dist for dist in linked} names_ms = {MatchSpec(s).name: MatchSpec(s) for s in specs} for name, def_ver in [('python', config.default_python), # Default version required, but only used for Python ('lua', None)]: ms = names_ms.get(name) if ms and ms.strictness > 1: # if any of the specifications mention the Python/Numpy version, # we don't need to add the default spec log.debug('H1 %s' % name) continue any_depends_on = any(ms2.name == name for spec in specs for fn in r.get_max_dists(MatchSpec(spec)) for ms2 in r.ms_depends(fn)) log.debug('H2 %s %s' % (name, any_depends_on)) if not any_depends_on and name not in names_ms: # if nothing depends on Python/Numpy AND the Python/Numpy is not # specified, we don't need to add the default spec log.debug('H2A %s' % name) continue if (any_depends_on and len(specs) >= 1 and MatchSpec(specs[0]).strictness == 3): # if something depends on Python/Numpy, but the spec is very # explicit, we also don't need to add the default spec log.debug('H2B %s' % name) continue if name in names_linked: # if Python/Numpy is already linked, we add that instead of the # default log.debug('H3 %s' % name) specs.append(dist2spec3v(names_linked[name])) continue if (name, def_ver) in [('python', '3.3'), ('python', '3.4'), ('python', '3.5')]: # Don't include Python 3 in the specs if this is the Python 3 # version of conda. continue specs.append('%s %s*' % (name, def_ver)) log.debug('HF specs=%r' % specs)
def execute(args, parser): import sys import conda.install as ci import conda.config as config import conda.plan as plan from conda.api import get_index from conda.cli import pscheck if len(args.pkg_names) == 0: sys.exit("""Error: no package names supplied # If you want to update to a newer version of Anaconda, type: # # $ conda update anaconda """) prefix = common.get_prefix(args) config.set_pkgs_dirs(prefix) linked = set(ci.name_dist(d) for d in ci.linked(prefix)) for name in args.pkg_names: common.arg2spec(name) if '=' in name: sys.exit("Invalid package name: '%s'" % (name)) if name not in linked: sys.exit("Error: package '%s' is not installed in %s" % (name, prefix)) common.ensure_override_channels_requires_channel(args) channel_urls = args.channel or () index = get_index(channel_urls=channel_urls, prepend=not args.override_channels) actions = plan.install_actions(prefix, index, args.pkg_names) if plan.nothing_to_do(actions): from conda.cli.main_list import list_packages regex = '^(%s)$' % '|'.join(args.pkg_names) print('# All packages already at latest version, nothing to do.') list_packages(prefix, regex) return print("Updating conda environment at %s" % prefix) plan.display_actions(actions, index) common.check_write('update', prefix) if not pscheck.main(args): common.confirm_yn(args) plan.execute_actions(actions, index, verbose=not args.quiet)
def add_defaults_to_specs(r, linked, specs): if r.explicit(specs): return log.debug('H0 specs=%r' % specs) names_linked = {install.name_dist(dist): dist for dist in linked} names_ms = {MatchSpec(s).name: MatchSpec(s) for s in specs} for name, def_ver in [ ('python', config.default_python), ]: #('numpy', config.default_numpy)]: ms = names_ms.get(name) if ms and ms.strictness > 1: # if any of the specifications mention the Python/Numpy version, # we don't need to add the default spec log.debug('H1 %s' % name) continue any_depends_on = any(ms2.name == name for spec in specs for fn in r.get_max_dists(MatchSpec(spec)) for ms2 in r.ms_depends(fn)) log.debug('H2 %s %s' % (name, any_depends_on)) if not any_depends_on and name not in names_ms: # if nothing depends on Python/Numpy AND the Python/Numpy is not # specified, we don't need to add the default spec log.debug('H2A %s' % name) continue if (any_depends_on and len(specs) >= 1 and MatchSpec(specs[0]).strictness == 3): # if something depends on Python/Numpy, but the spec is very # explicit, we also don't need to add the default spec log.debug('H2B %s' % name) continue if name in names_linked: # if Python/Numpy is already linked, we add that instead of the # default log.debug('H3 %s' % name) specs.append(dist2spec3v(names_linked[name])) continue if (name, def_ver) == ('python', '3.3'): # Don't include Python 3 in the specs if this is the Python 3 # version of conda. continue specs.append('%s %s*' % (name, def_ver)) log.debug('HF specs=%r' % specs)
def test_dist2(): for name in ('python', 'python-hyphen', ''): for version in ('2.7.0', '2.7.0rc1', ''): for build in ('0', 'py27_0', 'py35_0+g34fe21', ''): for channel in ('defaults', 'test', 'test-hyphen', 'http://bremen', 'https://anaconda.org/mcg', '<unknown>'): dist_noprefix = name + '-' + version + '-' + build quad = (name, version, build, channel) dist = dist_noprefix if channel == 'defaults' else channel + '::' + dist_noprefix for suffix in ('', '.tar.bz2', '[debug]', '.tar.bz2[debug]'): test = dist + suffix assert dist2quad(test) == quad assert dist2pair(test) == (channel, dist_noprefix) assert dist2name(test) == name assert name_dist(test) == name assert dist2dirname(test) == dist_noprefix assert dist2filename(test) == dist_noprefix + '.tar.bz2' assert dist2filename(test, '') == dist_noprefix
def execute_plan(plan, index=None, verbose=False): if verbose: from conda.console import setup_verbose_handlers setup_verbose_handlers() # set default prefix prefix = config.root_dir i = None cmds = cmds_from_plan(plan) for cmd, arg in cmds: if i is not None and cmd in progress_cmds: i += 1 getLogger('progress.update').info((install.name_dist(arg), i)) if cmd == PREFIX: prefix = arg elif cmd == PRINT: getLogger('print').info(arg) elif cmd == FETCH: fetch(index, arg) elif cmd == PROGRESS: i = 0 maxval = int(arg) getLogger('progress.start').info(maxval) elif cmd == EXTRACT: install.extract(config.pkgs_dirs[0], arg) elif cmd == RM_EXTRACTED: install.rm_extracted(config.pkgs_dirs[0], arg) elif cmd == RM_FETCHED: install.rm_fetched(config.pkgs_dirs[0], arg) elif cmd == LINK: link(prefix, arg, index=index) elif cmd == UNLINK: install.unlink(prefix, arg) elif cmd == SYMLINK_CONDA: install.symlink_conda(prefix, arg) else: raise Exception("Did not expect command: %r" % cmd) if i is not None and cmd in progress_cmds and maxval == i: i = None getLogger('progress.stop').info(None) install.messages(prefix)
def execute_plan(plan, index=None, verbose=False): if verbose: from conda.console import setup_verbose_handlers setup_verbose_handlers() # set default prefix prefix = config.root_dir i = None cmds = cmds_from_plan(plan) for cmd, arg in cmds: if i is not None and cmd in progress_cmds: i += 1 getLogger('progress.update').info((install.name_dist(arg), i)) if cmd == PREFIX: prefix = arg elif cmd == PRINT: getLogger('print').info(arg) elif cmd == FETCH: fetch(index, arg) elif cmd == PROGRESS: i = 0 maxval = int(arg) getLogger('progress.start').info(maxval) elif cmd == EXTRACT: install.extract(config.pkgs_dirs[0], arg) elif cmd == RM_EXTRACTED: install.rm_extracted(config.pkgs_dirs[0], arg) elif cmd == RM_FETCHED: install.rm_fetched(config.pkgs_dirs[0], arg) elif cmd == LINK: link(prefix, arg) elif cmd == UNLINK: install.unlink(prefix, arg) elif cmd == SYMLINK_CONDA: install.symlink_conda(prefix, arg) else: raise Exception("Did not expect command: %r" % cmd) if i is not None and cmd in progress_cmds and maxval == i: i = None getLogger('progress.stop').info(None) install.messages(prefix)
def add_defaults_to_specs(r, linked, specs): if r.explicit(specs): return log.debug('H0 specs=%r' % specs) names_linked = {install.name_dist(dist): dist for dist in linked} names_ms = {MatchSpec(s).name: MatchSpec(s) for s in specs} for name, def_ver in [('python', config.default_python), ('numpy', config.default_numpy)]: ms = names_ms.get(name) if ms and ms.strictness > 1: # if any of the specifications mention the Python/Numpy version, # we don't need to add the default spec log.debug('H1 %s' % name) continue any_depends_on = any(ms2.name == name for spec in specs for fn in r.get_max_dists(MatchSpec(spec)) for ms2 in r.ms_depends(fn)) log.debug('H2 %s %s' % (name, any_depends_on)) if not any_depends_on and name not in names_ms: # if nothing depends on Python/Numpy AND the Python/Numpy is not # specified, we don't need to add the default spec log.debug('H2A %s' % name) continue if (any_depends_on and len(specs) >= 1 and MatchSpec(specs[0]).strictness == 3): # if something depends on Python/Numpy, but the spec is very # explicit, we also don't need to add the default spec log.debug('H2B %s' % name) continue if name in names_linked: # if Python/Numpy is already linked, we also don't need to add # the default log.debug('H3 %s' % name) specs.append(dist2spec3v(names_linked[name])) continue specs.append('%s %s*' % (name, def_ver)) log.debug('HF specs=%r' % specs)
def execute_instructions(plan, index=None, verbose=False, _commands=None): """ Execute the instructions in the plan :param plan: A list of (instruction, arg) tuples :param index: The meta-data index :param verbose: verbose output :param _commands: (For testing only) dict mapping an instruction to executable if None then the default commands will be used """ if _commands is None: _commands = commands if verbose: from conda.console import setup_verbose_handlers setup_verbose_handlers() state = {'i': None, 'prefix': config.root_dir, 'index': index} for instruction, arg in plan: log.debug(' %s(%r)' % (instruction, arg)) if state['i'] is not None and instruction in progress_cmds: state['i'] += 1 getLogger('progress.update').info((install.name_dist(arg), state['i']-1)) cmd = _commands.get(instruction) if cmd is None: raise InvalidInstruction(instruction) cmd(state, arg) if (state['i'] is not None and instruction in progress_cmds and state['maxval'] == state['i']): state['i'] = None getLogger('progress.stop').info(None) install.messages(state['prefix'])
def execute_instructions(plan, index=None, verbose=False, _commands=None): """ Execute the instructions in the plan :param plan: A list of (instruction, arg) tuples :param index: The meta-data index :param verbose: verbose output :param _commands: (For testing only) dict mapping an instruction to executable if None then the default commands will be used """ if _commands is None: _commands = commands if verbose: from conda.console import setup_verbose_handlers setup_verbose_handlers() state = {'i': None, 'prefix': config.root_dir, 'index': index} for instruction, arg in plan: log.debug(' %s(%r)' % (instruction, arg)) if state['i'] is not None and instruction in progress_cmds: state['i'] += 1 getLogger('progress.update').info((install.name_dist(arg), state['i'] - 1)) cmd = _commands.get(instruction) if cmd is None: raise InvalidInstruction(instruction) cmd(state, arg) if (state['i'] is not None and instruction in progress_cmds and state['maxval'] == state['i']): state['i'] = None getLogger('progress.stop').info(None) install.messages(state['prefix'])
def test_dist2(): for name in ("python", "python-hyphen", ""): for version in ("2.7.0", "2.7.0rc1", ""): for build in ("0", "py27_0", "py35_0+g34fe21", ""): for channel in ( "defaults", "test", "test-hyphen", "http://bremen", "https://anaconda.org/mcg", "<unknown>", ): dist_noprefix = name + "-" + version + "-" + build quad = (name, version, build, channel) dist = dist_noprefix if channel == "defaults" else channel + "::" + dist_noprefix for suffix in ("", ".tar.bz2", "[debug]", ".tar.bz2[debug]"): test = dist + suffix assert dist2quad(test) == quad assert dist2pair(test) == (channel, dist_noprefix) assert dist2name(test) == name assert name_dist(test) == name assert dist2dirname(test) == dist_noprefix assert dist2filename(test) == dist_noprefix + ".tar.bz2" assert dist2filename(test, "") == dist_noprefix
def _name_fn(fn): assert fn.endswith('.tar.bz2') return install.name_dist(fn[:-8])
def discard_conda(dists): return [dist for dist in dists if not install.name_dist(dist) == 'conda']
def install(args, parser, command='install'): """ conda install, conda update, and conda create """ newenv = command == 'create' if newenv: common.ensure_name_or_prefix(args, command) prefix = common.get_prefix(args, search=not newenv) if newenv: check_prefix(prefix) config.set_pkgs_dirs(prefix) if command == 'update': if len(args.packages) == 0: sys.exit("""Error: no package names supplied # If you want to update to a newer version of Anaconda, type: # # $ conda update --prefix %s anaconda """ % prefix) if command == 'update': linked = ci.linked(prefix) for name in args.packages: common.arg2spec(name) if '=' in name: sys.exit("Invalid package name: '%s'" % (name)) if name not in set(ci.name_dist(d) for d in linked): sys.exit("Error: package '%s' is not installed in %s" % (name, prefix)) if newenv and args.clone: if args.packages: sys.exit('Error: did not expect any arguments for --clone') clone(args.clone, prefix) touch_nonadmin(prefix) print_activate(args.name if args.name else prefix) return if newenv and not args.no_default_packages: default_packages = config.create_default_packages[:] # Override defaults if they are specified at the command line for default_pkg in config.create_default_packages: if any(pkg.split('=')[0] == default_pkg for pkg in args.packages): default_packages.remove(default_pkg) args.packages.extend(default_packages) common.ensure_override_channels_requires_channel(args) channel_urls = args.channel or () if args.use_local: from conda.fetch import fetch_index from conda.utils import url_path try: from conda_build import config as build_config except ImportError: sys.exit("Error: you need to have 'conda-build' installed" " to use the --use-local option") # remove the cache such that a refetch is made, # this is necessary because we add the local build repo URL fetch_index.cache = {} index = get_index([url_path(build_config.croot)], use_cache=args.use_cache) else: index = get_index(channel_urls=channel_urls, prepend=not args.override_channels, use_cache=args.use_cache) # Don't update packages that are already up-to-date if command == 'update': r = Resolve(index) orig_packages = args.packages[:] for name in orig_packages: vers_inst = [dist.rsplit('-', 2)[1] for dist in linked if dist.rsplit('-', 2)[0] == name] build_inst = [dist.rsplit('-', 2)[2].rsplit('.tar.bz2', 1)[0] for dist in linked if dist.rsplit('-', 2)[0] == name] assert len(vers_inst) == 1, name assert len(build_inst) == 1, name pkgs = sorted(r.get_pkgs(MatchSpec(name))) if not pkgs: # Shouldn't happen? continue # This won't do the right thing for python 2 latest = pkgs[-1] if latest.version == vers_inst[0] and latest.build == build_inst[0]: args.packages.remove(name) if not args.packages: from conda.cli.main_list import list_packages regex = '^(%s)$' % '|'.join(orig_packages) print('# All requested packages already installed.') list_packages(prefix, regex) return # handle tar file containing conda packages if len(args.packages) == 1: tar_path = args.packages[0] if tar_path.endswith('.tar'): install_tar(prefix, tar_path, verbose=not args.quiet) return # handle explicit installs of conda packages if args.packages and all(s.endswith('.tar.bz2') for s in args.packages): from conda.misc import install_local_packages install_local_packages(prefix, args.packages, verbose=not args.quiet) return if any(s.endswith('.tar.bz2') for s in args.packages): sys.exit("cannot mix specifications with conda package filenames") if args.force: args.no_deps = True if args.file: specs = common.specs_from_url(args.file) else: specs = common.specs_from_args(args.packages) common.check_specs(prefix, specs) spec_names = set(s.split()[0] for s in specs) if args.no_deps: only_names = spec_names else: only_names = None if not isdir(prefix) and not newenv: if args.mkdir: try: os.makedirs(prefix) except OSError: sys.exit("Error: could not create directory: %s" % prefix) else: sys.exit("""\ Error: environment does not exist: %s # # Use 'conda create' to create an environment before installing packages # into it. #""" % prefix) actions = plan.install_actions(prefix, index, specs, force=args.force, only_names=only_names) if plan.nothing_to_do(actions): from conda.cli.main_list import list_packages regex = '^(%s)$' % '|'.join(spec_names) print('# All requested packages already installed.') list_packages(prefix, regex) return print() print("Package plan for installation in environment %s:" % prefix) plan.display_actions(actions, index) if command in {'install', 'update'}: common.check_write(command, prefix) if not pscheck.main(args): common.confirm_yn(args) plan.execute_actions(actions, index, verbose=not args.quiet) if newenv: touch_nonadmin(prefix) print_activate(args.name if args.name else prefix)
def install(args, parser, command='install'): """ conda install, conda update, and conda create """ newenv = bool(command == 'create') if newenv: common.ensure_name_or_prefix(args, command) prefix = common.get_prefix(args, search=not newenv) if newenv: check_prefix(prefix, json=args.json) if config.force_32bit and plan.is_root_prefix(prefix): common.error_and_exit("cannot use CONDA_FORCE_32BIT=1 in root env") if command == 'update': if not args.file: if not args.all and len(args.packages) == 0: common.error_and_exit("""no package names supplied # If you want to update to a newer version of Anaconda, type: # # $ conda update --prefix %s anaconda """ % prefix, json=args.json, error_type="ValueError") if command == 'update' and not args.all: linked = ci.linked(prefix) for name in args.packages: common.arg2spec(name, json=args.json) if '=' in name: common.error_and_exit("Invalid package name: '%s'" % (name), json=args.json, error_type="ValueError") if name not in set(ci.name_dist(d) for d in linked): common.error_and_exit("package '%s' is not installed in %s" % (name, prefix), json=args.json, error_type="ValueError") if newenv and not args.no_default_packages: default_packages = config.create_default_packages[:] # Override defaults if they are specified at the command line for default_pkg in config.create_default_packages: if any(pkg.split('=')[0] == default_pkg for pkg in args.packages): default_packages.remove(default_pkg) args.packages.extend(default_packages) else: default_packages = [] common.ensure_override_channels_requires_channel(args) channel_urls = args.channel or () specs = [] if args.file: for fpath in args.file: specs.extend(common.specs_from_url(fpath, json=args.json)) elif getattr(args, 'all', False): linked = ci.linked(prefix) if not linked: common.error_and_exit("There are no packages installed in the " "prefix %s" % prefix) for pkg in linked: name, ver, build = pkg.rsplit('-', 2) if name in getattr(args, '_skip', ['anaconda']): continue if name == 'python' and ver.startswith('2'): # Oh Python 2... specs.append('%s >=%s,<3' % (name, ver)) else: specs.append('%s' % name) specs.extend(common.specs_from_args(args.packages, json=args.json)) if command == 'install' and args.revision: get_revision(args.revision, json=args.json) elif not (newenv and args.clone): common.check_specs(prefix, specs, json=args.json, create=(command == 'create')) num_cp = sum(s.endswith('.tar.bz2') for s in args.packages) if num_cp: if num_cp == len(args.packages): depends = misc.install_local_packages(prefix, args.packages, verbose=not args.quiet) if args.no_deps: depends = [] specs = list(set(depends)) args.unknown = True else: common.error_and_exit( "cannot mix specifications with conda package filenames", json=args.json, error_type="ValueError") # handle tar file containing conda packages if len(args.packages) == 1: tar_path = args.packages[0] if tar_path.endswith('.tar'): depends = install_tar(prefix, tar_path, verbose=not args.quiet) if args.no_deps: depends = [] specs = list(set(depends)) args.unknown = True if args.use_local: from conda.fetch import fetch_index from conda.utils import url_path try: from conda_build.config import croot except ImportError: common.error_and_exit( "you need to have 'conda-build >= 1.7.1' installed" " to use the --use-local option", json=args.json, error_type="RuntimeError") # remove the cache such that a refetch is made, # this is necessary because we add the local build repo URL fetch_index.cache = {} if exists(croot): channel_urls = [url_path(croot)] + list(channel_urls) index = common.get_index_trap(channel_urls=channel_urls, prepend=not args.override_channels, use_cache=args.use_index_cache, unknown=args.unknown, json=args.json, offline=args.offline) if newenv and args.clone: if set(args.packages) - set(default_packages): common.error_and_exit('did not expect any arguments for --clone', json=args.json, error_type="ValueError") clone(args.clone, prefix, json=args.json, quiet=args.quiet, index=index) misc.append_env(prefix) misc.touch_nonadmin(prefix) if not args.json: print_activate(args.name if args.name else prefix) return # Don't update packages that are already up-to-date if command == 'update' and not (args.all or args.force): r = Resolve(index) orig_packages = args.packages[:] for name in orig_packages: installed_metadata = [ci.is_linked(prefix, dist) for dist in linked] vers_inst = [dist.rsplit('-', 2)[1] for dist in linked if dist.rsplit('-', 2)[0] == name] build_inst = [m['build_number'] for m in installed_metadata if m['name'] == name] try: assert len(vers_inst) == 1, name assert len(build_inst) == 1, name except AssertionError as e: if args.json: common.exception_and_exit(e, json=True) else: raise pkgs = sorted(r.get_pkgs(MatchSpec(name))) if not pkgs: # Shouldn't happen? continue latest = pkgs[-1] if (latest.version == vers_inst[0] and latest.build_number == build_inst[0]): args.packages.remove(name) if not args.packages: from conda.cli.main_list import print_packages if not args.json: regex = '^(%s)$' % '|'.join(orig_packages) print('# All requested packages already installed.') print_packages(prefix, regex) else: common.stdout_json_success( message='All requested packages already installed.') return if args.force: args.no_deps = True spec_names = set(s.split()[0] for s in specs) if args.no_deps: only_names = spec_names else: only_names = None if not isdir(prefix) and not newenv: if args.mkdir: try: os.makedirs(prefix) except OSError: common.error_and_exit("Error: could not create directory: %s" % prefix, json=args.json, error_type="OSError") else: common.error_and_exit("""\ environment does not exist: %s # # Use 'conda create' to create an environment before installing packages # into it. #""" % prefix, json=args.json, error_type="NoEnvironmentFound") try: if command == 'install' and args.revision: actions = plan.revert_actions(prefix, get_revision(args.revision)) else: with common.json_progress_bars(json=args.json and not args.quiet): actions = plan.install_actions(prefix, index, specs, force=args.force, only_names=only_names, pinned=args.pinned, minimal_hint=args.alt_hint, update_deps=args.update_deps) if config.always_copy or args.copy: new_link = [] for pkg in actions["LINK"]: dist, pkgs_dir, lt = inst.split_linkarg(pkg) lt = ci.LINK_COPY new_link.append("%s %s %d" % (dist, pkgs_dir, lt)) actions["LINK"] = new_link except NoPackagesFound as e: error_message = e.args[0] if command == 'update' and args.all: # Packages not found here just means they were installed but # cannot be found any more. Just skip them. if not args.json: print("Warning: %s, skipping" % error_message) else: # Not sure what to do here pass args._skip = getattr(args, '_skip', ['anaconda']) for pkg in e.pkgs: p = pkg.split()[0] if p in args._skip: # Avoid infinite recursion. This can happen if a spec # comes from elsewhere, like --file raise args._skip.append(p) return install(args, parser, command=command) else: packages = {index[fn]['name'] for fn in index} for pkg in e.pkgs: close = get_close_matches(pkg, packages, cutoff=0.7) if close: error_message += ("\n\nDid you mean one of these?" "\n\n %s" % (', '.join(close))) error_message += '\n\nYou can search for this package on anaconda.org with' error_message += '\n\n anaconda search -t conda %s' % pkg if len(e.pkgs) > 1: # Note this currently only happens with dependencies not found error_message += '\n\n (and similarly for the other packages)' if not find_executable('anaconda', include_others=False): error_message += '\n\nYou may need to install the anaconda-client command line client with' error_message += '\n\n conda install anaconda-client' pinned_specs = plan.get_pinned_specs(prefix) if pinned_specs: error_message += "\n\nNote that you have pinned specs in %s:" % join(prefix, 'conda-meta', 'pinned') error_message += "\n\n %r" % pinned_specs common.error_and_exit(error_message, json=args.json) except SystemExit as e: # Unsatisfiable package specifications/no such revision/import error error_type = 'UnsatisfiableSpecifications' if e.args and 'could not import' in e.args[0]: error_type = 'ImportError' common.exception_and_exit(e, json=args.json, newline=True, error_text=False, error_type=error_type) if plan.nothing_to_do(actions): from conda.cli.main_list import print_packages if not args.json: regex = '^(%s)$' % '|'.join(spec_names) print('\n# All requested packages already installed.') print_packages(prefix, regex) else: common.stdout_json_success( message='All requested packages already installed.') return if not args.json: print() print("Package plan for installation in environment %s:" % prefix) plan.display_actions(actions, index, show_channel_urls=args.show_channel_urls) if command in {'install', 'update'}: common.check_write(command, prefix) if not args.json: common.confirm_yn(args) elif args.dry_run: common.stdout_json_success(actions=actions, dry_run=True) sys.exit(0) with common.json_progress_bars(json=args.json and not args.quiet): try: plan.execute_actions(actions, index, verbose=not args.quiet) if not (command == 'update' and args.all): try: with open(join(prefix, 'conda-meta', 'history'), 'a') as f: f.write('# %s specs: %s\n' % (command, specs)) except IOError as e: if e.errno == errno.EACCES: log.debug("Can't write the history file") else: raise except RuntimeError as e: if len(e.args) > 0 and "LOCKERROR" in e.args[0]: error_type = "AlreadyLocked" else: error_type = "RuntimeError" common.exception_and_exit(e, error_type=error_type, json=args.json) except SystemExit as e: common.exception_and_exit(e, json=args.json) if newenv: misc.append_env(prefix) misc.touch_nonadmin(prefix) if not args.json: print_activate(args.name if args.name else prefix) if args.json: common.stdout_json_success(actions=actions)
def install(args, parser, command='install'): """ conda install, conda update, and conda create """ newenv = command == 'create' if newenv: common.ensure_name_or_prefix(args, command) prefix = common.get_prefix(args, search=not newenv) if newenv: check_prefix(prefix) config.set_pkgs_dirs(prefix) if command == 'update': if len(args.packages) == 0: sys.exit("""Error: no package names supplied # If you want to update to a newer version of Anaconda, type: # # $ conda update --prefix %s anaconda """ % prefix) if command == 'update': linked = set(ci.name_dist(d) for d in ci.linked(prefix)) for name in args.packages: common.arg2spec(name) if '=' in name: sys.exit("Invalid package name: '%s'" % (name)) if name not in linked: sys.exit("Error: package '%s' is not installed in %s" % (name, prefix)) if newenv and args.clone: if args.packages: sys.exit('Error: did not expect any arguments for --clone') clone(args.clone, prefix) touch_nonadmin(prefix) print_activate(args.name if args.name else prefix) return if newenv and not args.no_default_packages: args.packages.extend(config.create_default_packages) # handle tar file containaing conda packages if len(args.packages) == 1: tar_path = args.packages[0] if tar_path.endswith('.tar'): install_tar(prefix, tar_path, verbose=not args.quiet) return # handle explict installs of conda packages if args.packages and all(s.endswith('.tar.bz2') for s in args.packages): from conda.misc import install_local_packages install_local_packages(prefix, args.packages, verbose=not args.quiet) return if any(s.endswith('.tar.bz2') for s in args.packages): sys.exit("cannot mix specifications with conda package filenames") if args.force: args.no_deps = True if args.file: specs = common.specs_from_url(args.file) else: specs = common.specs_from_args(args.packages) common.check_specs(prefix, specs) spec_names = set(s.split()[0] for s in specs) if args.no_deps: only_names = spec_names else: only_names = None if not isdir(prefix) and not newenv: if args.mkdir: try: os.makedirs(prefix) except OSError: sys.exit("Error: could not create directory: %s" % prefix) else: sys.exit("""\ Error: environment does not exist: %s # # Use 'conda create' to create an environment before installing packages # into it. #""" % prefix) common.ensure_override_channels_requires_channel(args) channel_urls = args.channel or () index = get_index(channel_urls=channel_urls, prepend=not args.override_channels) if args.use_local: from conda.fetch import fetch_index from conda.utils import url_path try: from conda_build import config as build_config except ImportError: sys.exit("Error: you need to have 'conda-build' installed" " to use the --use-local option") # remove the cache such that a refetch is made, # this is necessary because we add the local build repo URL fetch_index.cache = {} index = get_index([url_path(build_config.croot)]) actions = plan.install_actions(prefix, index, specs, force=args.force, only_names=only_names) if plan.nothing_to_do(actions): from conda.cli.main_list import list_packages regex = '^(%s)$' % '|'.join(spec_names) print('# All requested packages already installed.') list_packages(prefix, regex) return print() print("Package plan for installation in environment %s:" % prefix) plan.display_actions(actions, index) if command in {'install', 'update'}: common.check_write(command, prefix) if not pscheck.main(args): common.confirm_yn(args) plan.execute_actions(actions, index, verbose=not args.quiet) if newenv: touch_nonadmin(prefix) print_activate(args.name if args.name else prefix)
def install(args, parser, command='install'): """ conda install, conda update, and conda create """ newenv = bool(command == 'create') if newenv: common.ensure_name_or_prefix(args, command) prefix = common.get_prefix(args, search=not newenv) if newenv: check_prefix(prefix) config.set_pkgs_dirs(prefix) if command == 'update': if args.all: if args.packages: sys.exit("""Error: --all cannot be used with packages""") else: if len(args.packages) == 0: sys.exit("""Error: no package names supplied # If you want to update to a newer version of Anaconda, type: # # $ conda update --prefix %s anaconda """ % prefix) if command == 'update': linked = ci.linked(prefix) for name in args.packages: common.arg2spec(name) if '=' in name: sys.exit("Invalid package name: '%s'" % (name)) if name not in set(ci.name_dist(d) for d in linked): sys.exit("Error: package '%s' is not installed in %s" % (name, prefix)) if newenv and args.clone: if args.packages: sys.exit('Error: did not expect any arguments for --clone') clone(args.clone, prefix) touch_nonadmin(prefix) print_activate(args.name if args.name else prefix) return if newenv and not args.no_default_packages: default_packages = config.create_default_packages[:] # Override defaults if they are specified at the command line for default_pkg in config.create_default_packages: if any(pkg.split('=')[0] == default_pkg for pkg in args.packages): default_packages.remove(default_pkg) args.packages.extend(default_packages) common.ensure_override_channels_requires_channel(args) channel_urls = args.channel or () if args.file: specs = common.specs_from_url(args.file) elif getattr(args, 'all', False): specs = [] linked = ci.linked(prefix) for pkg in linked: name, ver, build = pkg.rsplit('-', 2) if name == 'python' and ver.startswith('2'): # Oh Python 2... specs.append('%s >=%s,<3' % (name, ver)) else: specs.append('%s >=%s' % (name, ver)) else: specs = common.specs_from_args(args.packages) if command == 'install' and args.revision: get_revision(args.revision) else: common.check_specs(prefix, specs) if args.use_local: from conda.fetch import fetch_index from conda.utils import url_path try: from conda_build import config as build_config except ImportError: sys.exit("Error: you need to have 'conda-build' installed" " to use the --use-local option") # remove the cache such that a refetch is made, # this is necessary because we add the local build repo URL fetch_index.cache = {} index = get_index([url_path(build_config.croot)], use_cache=args.use_index_cache, unknown=args.unknown) else: index = get_index(channel_urls=channel_urls, prepend=not args.override_channels, use_cache=args.use_index_cache, unknown=args.unknown) # Don't update packages that are already up-to-date if command == 'update' and not args.all: r = Resolve(index) orig_packages = args.packages[:] for name in orig_packages: vers_inst = [dist.rsplit('-', 2)[1] for dist in linked if dist.rsplit('-', 2)[0] == name] build_inst = [dist.rsplit('-', 2)[2].rsplit('.tar.bz2', 1)[0] for dist in linked if dist.rsplit('-', 2)[0] == name] assert len(vers_inst) == 1, name assert len(build_inst) == 1, name pkgs = sorted(r.get_pkgs(MatchSpec(name))) if not pkgs: # Shouldn't happen? continue latest = pkgs[-1] if latest.version == vers_inst[0] and latest.build == build_inst[0]: args.packages.remove(name) if not args.packages: from conda.cli.main_list import list_packages regex = '^(%s)$' % '|'.join(orig_packages) print('# All requested packages already installed.') list_packages(prefix, regex) return # handle tar file containing conda packages if len(args.packages) == 1: tar_path = args.packages[0] if tar_path.endswith('.tar'): install_tar(prefix, tar_path, verbose=not args.quiet) return # handle explicit installs of conda packages if args.packages and all(s.endswith('.tar.bz2') for s in args.packages): from conda.misc import install_local_packages install_local_packages(prefix, args.packages, verbose=not args.quiet) return if any(s.endswith('.tar.bz2') for s in args.packages): sys.exit("cannot mix specifications with conda package filenames") if args.force: args.no_deps = True spec_names = set(s.split()[0] for s in specs) if args.no_deps: only_names = spec_names else: only_names = None if not isdir(prefix) and not newenv: if args.mkdir: try: os.makedirs(prefix) except OSError: sys.exit("Error: could not create directory: %s" % prefix) else: sys.exit("""\ Error: environment does not exist: %s # # Use 'conda create' to create an environment before installing packages # into it. #""" % prefix) if command == 'install' and args.revision: actions = plan.revert_actions(prefix, get_revision(args.revision)) else: actions = plan.install_actions(prefix, index, specs, force=args.force, only_names=only_names) if plan.nothing_to_do(actions): from conda.cli.main_list import list_packages regex = '^(%s)$' % '|'.join(spec_names) print('# All requested packages already installed.') list_packages(prefix, regex) return print() print("Package plan for installation in environment %s:" % prefix) plan.display_actions(actions, index) if command in {'install', 'update'}: common.check_write(command, prefix) if not pscheck.main(args): common.confirm_yn(args) plan.execute_actions(actions, index, verbose=not args.quiet) if newenv: touch_nonadmin(prefix) print_activate(args.name if args.name else prefix)
def explicit(specs, prefix, verbose=False, force_extract=True, fetch_args=None): actions = defaultdict(list) actions['PREFIX'] = prefix actions['op_order'] = RM_FETCHED, FETCH, RM_EXTRACTED, EXTRACT, UNLINK, LINK linked = {install.name_dist(dist): dist for dist in install.linked(prefix)} fetch_args = fetch_args or {} index = {} verifies = [] channels = {} for spec in specs: if spec == '@EXPLICIT': continue # Format: (url|path)(:#md5)? m = url_pat.match(spec) if m is None: sys.exit('Could not parse explicit URL: %s' % spec) url, md5 = m.group('url') + '/' + m.group('fn'), m.group('md5') if not is_url(url): if not isfile(url): sys.exit('Error: file not found: %s' % url) url = utils.url_path(url) url_p, fn = url.rsplit('/', 1) # See if the URL refers to a package in our cache prefix = pkg_path = dir_path = None if url_p.startswith('file://'): prefix = install.cached_url(url) # If not, determine the channel name from the URL if prefix is None: _, schannel = url_channel(url) prefix = '' if schannel == 'defaults' else schannel + '::' fn = prefix + fn dist = fn[:-8] pkg_path = install.is_fetched(dist) dir_path = install.is_extracted(dist) # Don't re-fetch unless there is an MD5 mismatch if pkg_path and (md5 and md5_file(pkg_path) != md5): # This removes any extracted copies as well actions[RM_FETCHED].append(dist) pkg_path = dir_path = None # Don't re-extract unless forced, or if we can't check the md5 if dir_path and (force_extract or md5 and not pkg_path): actions[RM_EXTRACTED].append(dist) dir_path = None if not dir_path: if not pkg_path: _, conflict = install.find_new_location(dist) if conflict: actions[RM_FETCHED].append(conflict) actions[FETCH].append(dist) if md5: # Need to verify against the package index verifies.append((dist + '.tar.bz2', md5)) channels[url_p + '/'] = (schannel, 0) actions[EXTRACT].append(dist) # unlink any installed package with that name name = install.name_dist(dist) if name in linked: actions[UNLINK].append(linked[name]) actions[LINK].append(dist) # Finish the MD5 verification if verifies: index = fetch_index(channels, **fetch_args) for fn, md5 in verifies: info = index.get(fn) if info is None: sys.exit("Error: no package '%s' in index" % fn) if 'md5' not in info: sys.stderr.write('Warning: cannot lookup MD5 of: %s' % fn) if info['md5'] != md5: sys.exit( 'MD5 mismatch for: %s\n spec: %s\n repo: %s' % (fn, md5, info['md5'])) execute_actions(actions, index=index, verbose=verbose) return actions
def install(args, parser, command='install'): """ conda install, conda update, and conda create """ newenv = bool(command == 'create') isupdate = bool(command == 'update') isinstall = bool(command == 'install') if newenv: common.ensure_name_or_prefix(args, command) prefix = common.get_prefix(args, search=not newenv) if newenv: check_prefix(prefix, json=args.json) if force_32bit and plan.is_root_prefix(prefix): common.error_and_exit("cannot use CONDA_FORCE_32BIT=1 in root env") if isupdate and not (args.file or args.all or args.packages): common.error_and_exit("""no package names supplied # If you want to update to a newer version of Anaconda, type: # # $ conda update --prefix %s anaconda """ % prefix, json=args.json, error_type="ValueError") linked = ci.linked(prefix) lnames = {ci.name_dist(d) for d in linked} if isupdate and not args.all: for name in args.packages: common.arg2spec(name, json=args.json, update=True) if name not in lnames: common.error_and_exit("Package '%s' is not installed in %s" % (name, prefix), json=args.json, error_type="ValueError") if newenv and not args.no_default_packages: default_packages = create_default_packages[:] # Override defaults if they are specified at the command line for default_pkg in create_default_packages: if any(pkg.split('=')[0] == default_pkg for pkg in args.packages): default_packages.remove(default_pkg) args.packages.extend(default_packages) else: default_packages = [] common.ensure_use_local(args) common.ensure_override_channels_requires_channel(args) channel_urls = args.channel or () specs = [] if args.file: for fpath in args.file: specs.extend(common.specs_from_url(fpath, json=args.json)) if '@EXPLICIT' in specs: misc.explicit(specs, prefix, verbose=not args.quiet) return elif getattr(args, 'all', False): if not linked: common.error_and_exit("There are no packages installed in the " "prefix %s" % prefix) specs.extend(nm for nm in lnames) specs.extend(common.specs_from_args(args.packages, json=args.json)) if isinstall and args.revision: get_revision(args.revision, json=args.json) elif not (newenv and args.clone): common.check_specs(prefix, specs, json=args.json, create=(command == 'create')) num_cp = sum(s.endswith('.tar.bz2') for s in args.packages) if num_cp: if num_cp == len(args.packages): misc.explicit(args.packages, prefix, verbose=not args.quiet) return else: common.error_and_exit( "cannot mix specifications with conda package filenames", json=args.json, error_type="ValueError") # handle tar file containing conda packages if len(args.packages) == 1: tar_path = args.packages[0] if tar_path.endswith('.tar'): install_tar(prefix, tar_path, verbose=not args.quiet) return if newenv and args.clone: if set(args.packages) - set(default_packages): common.error_and_exit('did not expect any arguments for --clone', json=args.json, error_type="ValueError") clone(args.clone, prefix, json=args.json, quiet=args.quiet, fetch_args={'use_cache': args.use_index_cache, 'unknown': args.unknown}) misc.append_env(prefix) misc.touch_nonadmin(prefix) if not args.json: print_activate(args.name if args.name else prefix) return index = common.get_index_trap(channel_urls=channel_urls, prepend=not args.override_channels, use_local=args.use_local, use_cache=args.use_index_cache, unknown=args.unknown, json=args.json, offline=args.offline, prefix=prefix) r = Resolve(index) ospecs = list(specs) plan.add_defaults_to_specs(r, linked, specs, update=isupdate) # Don't update packages that are already up-to-date if isupdate and not (args.all or args.force): orig_packages = args.packages[:] installed_metadata = [ci.is_linked(prefix, dist) for dist in linked] for name in orig_packages: vers_inst = [m['version'] for m in installed_metadata if m['name'] == name] build_inst = [m['build_number'] for m in installed_metadata if m['name'] == name] try: assert len(vers_inst) == 1, name assert len(build_inst) == 1, name except AssertionError as e: if args.json: common.exception_and_exit(e, json=True) else: raise pkgs = sorted(r.get_pkgs(name)) if not pkgs: # Shouldn't happen? continue latest = pkgs[-1] if (latest.version == vers_inst[0] and latest.build_number == build_inst[0]): args.packages.remove(name) if not args.packages: from conda.cli.main_list import print_packages if not args.json: regex = '^(%s)$' % '|'.join(orig_packages) print('# All requested packages already installed.') print_packages(prefix, regex) else: common.stdout_json_success( message='All requested packages already installed.') return if args.force: args.no_deps = True if args.no_deps: only_names = set(s.split()[0] for s in ospecs) else: only_names = None if not isdir(prefix) and not newenv: if args.mkdir: try: os.makedirs(prefix) except OSError: common.error_and_exit("Error: could not create directory: %s" % prefix, json=args.json, error_type="OSError") else: common.error_and_exit("""\ environment does not exist: %s # # Use 'conda create' to create an environment before installing packages # into it. #""" % prefix, json=args.json, error_type="NoEnvironmentFound") try: if isinstall and args.revision: actions = plan.revert_actions(prefix, get_revision(args.revision)) else: with common.json_progress_bars(json=args.json and not args.quiet): actions = plan.install_actions(prefix, index, specs, force=args.force, only_names=only_names, pinned=args.pinned, always_copy=args.copy, minimal_hint=args.alt_hint, update_deps=args.update_deps) except NoPackagesFound as e: error_message = e.args[0] if isupdate and args.all: # Packages not found here just means they were installed but # cannot be found any more. Just skip them. if not args.json: print("Warning: %s, skipping" % error_message) else: # Not sure what to do here pass args._skip = getattr(args, '_skip', ['anaconda']) for pkg in e.pkgs: p = pkg.split()[0] if p in args._skip: # Avoid infinite recursion. This can happen if a spec # comes from elsewhere, like --file raise args._skip.append(p) return install(args, parser, command=command) else: packages = {index[fn]['name'] for fn in index} nfound = 0 for pkg in sorted(e.pkgs): pkg = pkg.split()[0] if pkg in packages: continue close = get_close_matches(pkg, packages, cutoff=0.7) if not close: continue if nfound == 0: error_message += "\n\nClose matches found; did you mean one of these?\n" error_message += "\n %s: %s" % (pkg, ', '.join(close)) nfound += 1 error_message += '\n\nYou can search for packages on anaconda.org with' error_message += '\n\n anaconda search -t conda %s' % pkg if len(e.pkgs) > 1: # Note this currently only happens with dependencies not found error_message += '\n\n(and similarly for the other packages)' if not find_executable('anaconda', include_others=False): error_message += '\n\nYou may need to install the anaconda-client' error_message += ' command line client with' error_message += '\n\n conda install anaconda-client' pinned_specs = plan.get_pinned_specs(prefix) if pinned_specs: path = join(prefix, 'conda-meta', 'pinned') error_message += "\n\nNote that you have pinned specs in %s:" % path error_message += "\n\n %r" % pinned_specs common.error_and_exit(error_message, json=args.json) except (Unsatisfiable, SystemExit) as e: # Unsatisfiable package specifications/no such revision/import error error_type = 'UnsatisfiableSpecifications' if e.args and 'could not import' in e.args[0]: error_type = 'ImportError' common.exception_and_exit(e, json=args.json, newline=True, error_text=False, error_type=error_type) if plan.nothing_to_do(actions): from conda.cli.main_list import print_packages if not args.json: regex = '^(%s)$' % '|'.join(s.split()[0] for s in ospecs) print('\n# All requested packages already installed.') print_packages(prefix, regex) else: common.stdout_json_success( message='All requested packages already installed.') return if not args.json: print() print("Package plan for installation in environment %s:" % prefix) plan.display_actions(actions, index, show_channel_urls=args.show_channel_urls) if command in {'install', 'update'}: common.check_write(command, prefix) if not args.json: common.confirm_yn(args) elif args.dry_run: common.stdout_json_success(actions=actions, dry_run=True) sys.exit(0) with common.json_progress_bars(json=args.json and not args.quiet): try: plan.execute_actions(actions, index, verbose=not args.quiet) if not (command == 'update' and args.all): try: with open(join(prefix, 'conda-meta', 'history'), 'a') as f: f.write('# %s specs: %s\n' % (command, specs)) except IOError as e: if e.errno == errno.EACCES: log.debug("Can't write the history file") else: raise except RuntimeError as e: if len(e.args) > 0 and "LOCKERROR" in e.args[0]: error_type = "AlreadyLocked" else: error_type = "RuntimeError" common.exception_and_exit(e, error_type=error_type, json=args.json) except SystemExit as e: common.exception_and_exit(e, json=args.json) if newenv: misc.append_env(prefix) misc.touch_nonadmin(prefix) if not args.json: print_activate(args.name if args.name else prefix) if args.json: common.stdout_json_success(actions=actions)
def install(args, parser, command='install'): """ conda install, conda update, and conda create """ newenv = bool(command == 'create') if newenv: common.ensure_name_or_prefix(args, command) prefix = common.get_prefix(args, search=not newenv) if newenv: check_prefix(prefix, json=args.json) if command == 'update': if args.all: if args.packages: common.error_and_exit("""--all cannot be used with packages""", json=args.json, error_type="ValueError") else: if len(args.packages) == 0: common.error_and_exit("""no package names supplied # If you want to update to a newer version of Anaconda, type: # # $ conda update --prefix %s anaconda """ % prefix, json=args.json, error_type="ValueError") if command == 'update': linked = ci.linked(prefix) for name in args.packages: common.arg2spec(name, json=args.json) if '=' in name: common.error_and_exit("Invalid package name: '%s'" % (name), json=args.json, error_type="ValueError") if name not in set(ci.name_dist(d) for d in linked): common.error_and_exit("package '%s' is not installed in %s" % (name, prefix), json=args.json, error_type="ValueError") if newenv and args.clone: if args.packages: common.error_and_exit('did not expect any arguments for --clone', json=args.json, error_type="ValueError") clone(args.clone, prefix, json=args.json, quiet=args.quiet) touch_nonadmin(prefix) if not args.json: print_activate(args.name if args.name else prefix) return if newenv and not args.no_default_packages: default_packages = config.create_default_packages[:] # Override defaults if they are specified at the command line for default_pkg in config.create_default_packages: if any(pkg.split('=')[0] == default_pkg for pkg in args.packages): default_packages.remove(default_pkg) args.packages.extend(default_packages) common.ensure_override_channels_requires_channel(args) channel_urls = args.channel or () specs = [] if args.file: specs.extend(common.specs_from_url(args.file, json=args.json)) elif getattr(args, 'all', False): linked = ci.linked(prefix) for pkg in linked: name, ver, build = pkg.rsplit('-', 2) if name == 'python' and ver.startswith('2'): # Oh Python 2... specs.append('%s >=%s,<3' % (name, ver)) else: specs.append('%s >=%s' % (name, ver)) specs.extend(common.specs_from_args(args.packages, json=args.json)) if command == 'install' and args.revision: get_revision(args.revision, json=args.json) else: common.check_specs(prefix, specs, json=args.json) if args.use_local: from conda.fetch import fetch_index from conda.utils import url_path try: from conda_build import config as build_config except ImportError: common.error_and_exit("you need to have 'conda-build' installed" " to use the --use-local option", json=args.json, error_type="RuntimeError") # remove the cache such that a refetch is made, # this is necessary because we add the local build repo URL fetch_index.cache = {} index = common.get_index_trap([url_path(build_config.croot)], use_cache=args.use_index_cache, unknown=args.unknown, json=args.json) else: index = common.get_index_trap(channel_urls=channel_urls, prepend=not args.override_channels, use_cache=args.use_index_cache, unknown=args.unknown, json=args.json) # Don't update packages that are already up-to-date if command == 'update' and not args.all: r = Resolve(index) orig_packages = args.packages[:] for name in orig_packages: installed_metadata = [ci.is_linked(prefix, dist) for dist in linked] vers_inst = [dist.rsplit('-', 2)[1] for dist in linked if dist.rsplit('-', 2)[0] == name] build_inst = [m['build_number'] for m in installed_metadata if m['name'] == name] try: assert len(vers_inst) == 1, name assert len(build_inst) == 1, name except AssertionError as e: if args.json: common.exception_and_exit(e, json=True) else: raise pkgs = sorted(r.get_pkgs(MatchSpec(name))) if not pkgs: # Shouldn't happen? continue latest = pkgs[-1] if latest.version == vers_inst[0] and latest.build_number == build_inst[0]: args.packages.remove(name) if not args.packages: from conda.cli.main_list import print_packages if not args.json: regex = '^(%s)$' % '|'.join(orig_packages) print('# All requested packages already installed.') print_packages(prefix, regex) else: common.stdout_json_success(message='All requested packages already installed.') return # handle tar file containing conda packages if len(args.packages) == 1: tar_path = args.packages[0] if tar_path.endswith('.tar'): install_tar(prefix, tar_path, verbose=not args.quiet) return # handle explicit installs of conda packages if args.packages and all(s.endswith('.tar.bz2') for s in args.packages): from conda.misc import install_local_packages install_local_packages(prefix, args.packages, verbose=not args.quiet) return if any(s.endswith('.tar.bz2') for s in args.packages): common.error_and_exit("cannot mix specifications with conda package filenames", json=args.json, error_type="ValueError") if args.force: args.no_deps = True spec_names = set(s.split()[0] for s in specs) if args.no_deps: only_names = spec_names else: only_names = None if not isdir(prefix) and not newenv: if args.mkdir: try: os.makedirs(prefix) except OSError: common.error_and_exit("Error: could not create directory: %s" % prefix, json=args.json, error_type="OSError") else: common.error_and_exit("""\ environment does not exist: %s # # Use 'conda create' to create an environment before installing packages # into it. #""" % prefix, json=args.json, error_type="NoEnvironmentFound") try: if command == 'install' and args.revision: actions = plan.revert_actions(prefix, get_revision(args.revision)) else: actions = plan.install_actions(prefix, index, specs, force=args.force, only_names=only_names, pinned=args.pinned, minimal_hint=args.alt_hint) except NoPackagesFound as e: common.exception_and_exit(e, json=args.json) except SystemExit as e: # Unsatisfiable package specifications/no such revision/import error error_type = 'UnsatisfiableSpecifications' if e.args and 'could not import' in e.args[0]: error_type = 'ImportError' common.exception_and_exit(e, json=args.json, newline=True, error_text=False, error_type=error_type) if plan.nothing_to_do(actions): from conda.cli.main_list import print_packages if not args.json: regex = '^(%s)$' % '|'.join(spec_names) print('\n# All requested packages already installed.') print_packages(prefix, regex) else: common.stdout_json_success(message='All requested packages already installed.') return if not args.json: print() print("Package plan for installation in environment %s:" % prefix) plan.display_actions(actions, index) if command in {'install', 'update'}: common.check_write(command, prefix) if not args.json: if not pscheck.main(args): common.confirm_yn(args) else: if (sys.platform == 'win32' and not args.force_pscheck and not pscheck.check_processes(verbose=False)): common.error_and_exit("Cannot continue operation while processes " "from packages are running without --force-pscheck.", json=True, error_type="ProcessesStillRunning") elif args.dry_run: common.stdout_json_success(actions=actions, dry_run=True) sys.exit(0) with common.json_progress_bars(json=args.json and not args.quiet): try: plan.execute_actions(actions, index, verbose=not args.quiet) except RuntimeError as e: if len(e.args) > 0 and "LOCKERROR" in e.args[0]: error_type = "AlreadyLocked" else: error_type = "RuntimeError" common.exception_and_exit(e, error_type=error_type, json=args.json) except SystemExit as e: common.exception_and_exit(e, json=args.json) if newenv: touch_nonadmin(prefix) if not args.json: print_activate(args.name if args.name else prefix) if args.json: common.stdout_json_success(actions=actions)
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 = {} mustnt_have = {} for fn in r.solve(specs, [d + '.tar.bz2' for d in linked], config.track_features, minimal_hint=minimal_hint, update_deps=update_deps): dist = fn[:-8] name = install.name_dist(dist) if name.startswith('remove '): name = name.split('remove ', 1)[1] dist = dist.split('remove ', 1)[1] mustnt_have[name] = dist else: 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
def explicit(specs, prefix, verbose=False, force_extract=True, fetch_args=None): actions = defaultdict(list) actions['PREFIX'] = prefix actions[ 'op_order'] = RM_FETCHED, FETCH, RM_EXTRACTED, EXTRACT, UNLINK, LINK linked = {install.name_dist(dist): dist for dist in install.linked(prefix)} fetch_args = fetch_args or {} index = {} verifies = [] channels = {} for spec in specs: if spec == '@EXPLICIT': continue # Format: (url|path)(:#md5)? m = url_pat.match(spec) if m is None: sys.exit('Could not parse explicit URL: %s' % spec) url, md5 = m.group('url') + '/' + m.group('fn'), m.group('md5') if not is_url(url): if not isfile(url): sys.exit('Error: file not found: %s' % url) url = utils.url_path(url) url_p, fn = url.rsplit('/', 1) # See if the URL refers to a package in our cache prefix = pkg_path = dir_path = None if url_p.startswith('file://'): prefix = install.cached_url(url) # If not, determine the channel name from the URL if prefix is None: _, schannel = url_channel(url) prefix = '' if schannel == 'defaults' else schannel + '::' fn = prefix + fn dist = fn[:-8] pkg_path = install.is_fetched(dist) dir_path = install.is_extracted(dist) # Don't re-fetch unless there is an MD5 mismatch if pkg_path and (md5 and md5_file(pkg_path) != md5): # This removes any extracted copies as well actions[RM_FETCHED].append(dist) pkg_path = dir_path = None # Don't re-extract unless forced, or if we can't check the md5 if dir_path and (force_extract or md5 and not pkg_path): actions[RM_EXTRACTED].append(dist) dir_path = None if not dir_path: if not pkg_path: _, conflict = install.find_new_location(dist) if conflict: actions[RM_FETCHED].append(conflict) channels[url_p + '/'] = (schannel, 0) actions[FETCH].append(dist) verifies.append((dist + '.tar.bz2', md5)) actions[EXTRACT].append(dist) # unlink any installed package with that name name = install.name_dist(dist) if name in linked: actions[UNLINK].append(linked[name]) actions[LINK].append(dist) # Pull the repodata for channels we are using if channels: index.update(fetch_index(channels, **fetch_args)) # Finish the MD5 verification for fn, md5 in verifies: info = index.get(fn) if info is None: sys.exit("Error: no package '%s' in index" % fn) if md5 and 'md5' not in info: sys.stderr.write('Warning: cannot lookup MD5 of: %s' % fn) if md5 and info['md5'] != md5: sys.exit('MD5 mismatch for: %s\n spec: %s\n repo: %s' % (fn, md5, info['md5'])) execute_actions(actions, index=index, verbose=verbose) return actions
def install(args, parser, command='install'): """ conda install, conda update, and conda create """ newenv = bool(command == 'create') if newenv: common.ensure_name_or_prefix(args, command) prefix = common.get_prefix(args, search=not newenv) if newenv: check_prefix(prefix, json=args.json) if command == 'update': if args.all: if args.packages: common.error_and_exit("""--all cannot be used with packages""", json=args.json, error_type="ValueError") else: if len(args.packages) == 0: common.error_and_exit("""no package names supplied # If you want to update to a newer version of Anaconda, type: # # $ conda update --prefix %s anaconda """ % prefix, json=args.json, error_type="ValueError") if command == 'update': linked = ci.linked(prefix) for name in args.packages: common.arg2spec(name, json=args.json) if '=' in name: common.error_and_exit("Invalid package name: '%s'" % (name), json=args.json, error_type="ValueError") if name not in set(ci.name_dist(d) for d in linked): common.error_and_exit("package '%s' is not installed in %s" % (name, prefix), json=args.json, error_type="ValueError") if newenv and args.clone: if args.packages: common.error_and_exit('did not expect any arguments for --clone', json=args.json, error_type="ValueError") clone(args.clone, prefix, json=args.json, quiet=args.quiet) touch_nonadmin(prefix) if not args.json: print_activate(args.name if args.name else prefix) return if newenv and not args.no_default_packages: default_packages = config.create_default_packages[:] # Override defaults if they are specified at the command line for default_pkg in config.create_default_packages: if any(pkg.split('=')[0] == default_pkg for pkg in args.packages): default_packages.remove(default_pkg) args.packages.extend(default_packages) common.ensure_override_channels_requires_channel(args) channel_urls = args.channel or () specs = [] if args.file: specs.extend(common.specs_from_url(args.file, json=args.json)) elif getattr(args, 'all', False): linked = ci.linked(prefix) for pkg in linked: name, ver, build = pkg.rsplit('-', 2) if name == 'python' and ver.startswith('2'): # Oh Python 2... specs.append('%s >=%s,<3' % (name, ver)) else: specs.append('%s >=%s' % (name, ver)) specs.extend(common.specs_from_args(args.packages, json=args.json)) if command == 'install' and args.revision: get_revision(args.revision, json=args.json) else: common.check_specs(prefix, specs, json=args.json) if args.use_local: from conda.fetch import fetch_index from conda.utils import url_path try: from conda_build import config as build_config except ImportError: common.error_and_exit( "you need to have 'conda-build' installed" " to use the --use-local option", json=args.json, error_type="RuntimeError") # remove the cache such that a refetch is made, # this is necessary because we add the local build repo URL fetch_index.cache = {} index = common.get_index_trap([url_path(build_config.croot)], use_cache=args.use_index_cache, unknown=args.unknown, json=args.json) else: index = common.get_index_trap(channel_urls=channel_urls, prepend=not args.override_channels, use_cache=args.use_index_cache, unknown=args.unknown, json=args.json) # Don't update packages that are already up-to-date if command == 'update' and not args.all: r = Resolve(index) orig_packages = args.packages[:] for name in orig_packages: installed_metadata = [ ci.is_linked(prefix, dist) for dist in linked ] vers_inst = [ dist.rsplit('-', 2)[1] for dist in linked if dist.rsplit('-', 2)[0] == name ] build_inst = [ m['build_number'] for m in installed_metadata if m['name'] == name ] try: assert len(vers_inst) == 1, name assert len(build_inst) == 1, name except AssertionError as e: if args.json: common.exception_and_exit(e, json=True) else: raise pkgs = sorted(r.get_pkgs(MatchSpec(name))) if not pkgs: # Shouldn't happen? continue latest = pkgs[-1] if latest.version == vers_inst[ 0] and latest.build_number == build_inst[0]: args.packages.remove(name) if not args.packages: from conda.cli.main_list import print_packages if not args.json: regex = '^(%s)$' % '|'.join(orig_packages) print('# All requested packages already installed.') print_packages(prefix, regex) else: common.stdout_json_success( message='All requested packages already installed.') return # handle tar file containing conda packages if len(args.packages) == 1: tar_path = args.packages[0] if tar_path.endswith('.tar'): install_tar(prefix, tar_path, verbose=not args.quiet) return # handle explicit installs of conda packages if args.packages and all(s.endswith('.tar.bz2') for s in args.packages): from conda.misc import install_local_packages install_local_packages(prefix, args.packages, verbose=not args.quiet) return if any(s.endswith('.tar.bz2') for s in args.packages): common.error_and_exit( "cannot mix specifications with conda package filenames", json=args.json, error_type="ValueError") if args.force: args.no_deps = True spec_names = set(s.split()[0] for s in specs) if args.no_deps: only_names = spec_names else: only_names = None if not isdir(prefix) and not newenv: if args.mkdir: try: os.makedirs(prefix) except OSError: common.error_and_exit("Error: could not create directory: %s" % prefix, json=args.json, error_type="OSError") else: common.error_and_exit("""\ environment does not exist: %s # # Use 'conda create' to create an environment before installing packages # into it. #""" % prefix, json=args.json, error_type="NoEnvironmentFound") try: if command == 'install' and args.revision: actions = plan.revert_actions(prefix, get_revision(args.revision)) else: actions = plan.install_actions(prefix, index, specs, force=args.force, only_names=only_names, pinned=args.pinned, minimal_hint=args.alt_hint) except NoPackagesFound as e: error_message = e.args[0] packages = {index[fn]['name'] for fn in index} for pkg in e.pkgs: close = get_close_matches(pkg, packages) if close: error_message += "\n\nDid you mean one of these?\n %s" % ( ', '.join(close)) error_message += '\n\nYou can search for this package on Binstar with' error_message += '\n\n binstar search -t conda %s' % pkg error_message += '\n\nYou may need to install the Binstar command line client with' error_message += '\n\n conda install binstar' common.error_and_exit(error_message, json=args.json) except SystemExit as e: # Unsatisfiable package specifications/no such revision/import error error_type = 'UnsatisfiableSpecifications' if e.args and 'could not import' in e.args[0]: error_type = 'ImportError' common.exception_and_exit(e, json=args.json, newline=True, error_text=False, error_type=error_type) if plan.nothing_to_do(actions): from conda.cli.main_list import print_packages if not args.json: regex = '^(%s)$' % '|'.join(spec_names) print('\n# All requested packages already installed.') print_packages(prefix, regex) else: common.stdout_json_success( message='All requested packages already installed.') return if not args.json: print() print("Package plan for installation in environment %s:" % prefix) plan.display_actions(actions, index) if command in {'install', 'update'}: common.check_write(command, prefix) if not args.json: if not pscheck.main(args): common.confirm_yn(args) else: if (sys.platform == 'win32' and not args.force_pscheck and not pscheck.check_processes(verbose=False)): common.error_and_exit( "Cannot continue operation while processes " "from packages are running without --force-pscheck.", json=True, error_type="ProcessesStillRunning") elif args.dry_run: common.stdout_json_success(actions=actions, dry_run=True) sys.exit(0) with common.json_progress_bars(json=args.json and not args.quiet): try: plan.execute_actions(actions, index, verbose=not args.quiet) except RuntimeError as e: if len(e.args) > 0 and "LOCKERROR" in e.args[0]: error_type = "AlreadyLocked" else: error_type = "RuntimeError" common.exception_and_exit(e, error_type=error_type, json=args.json) except SystemExit as e: common.exception_and_exit(e, json=args.json) if newenv: touch_nonadmin(prefix) if not args.json: print_activate(args.name if args.name else prefix) if args.json: common.stdout_json_success(actions=actions)
def install(args, parser, command='install'): """ conda install, conda update, and conda create """ newenv = bool(command == 'create') if newenv: common.ensure_name_or_prefix(args, command) prefix = common.get_prefix(args, search=not newenv) if newenv: check_prefix(prefix, json=args.json) if config.force_32bit and plan.is_root_prefix(prefix): common.error_and_exit("cannot use CONDA_FORCE_32BIT=1 in root env") if command == 'update': if args.all: if args.packages: common.error_and_exit("""--all cannot be used with packages""", json=args.json, error_type="ValueError") elif not args.file: if len(args.packages) == 0: common.error_and_exit("""no package names supplied # If you want to update to a newer version of Anaconda, type: # # $ conda update --prefix %s anaconda """ % prefix, json=args.json, error_type="ValueError") if command == 'update': linked = ci.linked(prefix) for name in args.packages: common.arg2spec(name, json=args.json) if '=' in name: common.error_and_exit("Invalid package name: '%s'" % (name), json=args.json, error_type="ValueError") if name not in set(ci.name_dist(d) for d in linked): common.error_and_exit("package '%s' is not installed in %s" % (name, prefix), json=args.json, error_type="ValueError") if newenv and not args.no_default_packages: default_packages = config.create_default_packages[:] # Override defaults if they are specified at the command line for default_pkg in config.create_default_packages: if any(pkg.split('=')[0] == default_pkg for pkg in args.packages): default_packages.remove(default_pkg) args.packages.extend(default_packages) else: default_packages = [] common.ensure_override_channels_requires_channel(args) channel_urls = args.channel or () specs = [] if args.file: for fpath in args.file: specs.extend(common.specs_from_url(fpath, json=args.json)) elif getattr(args, 'all', False): linked = ci.linked(prefix) if not linked: common.error_and_exit("There are no packages installed in the " "prefix %s" % prefix) for pkg in linked: name, ver, build = pkg.rsplit('-', 2) if name in getattr(args, '_skip', ['anaconda']): continue if name == 'python' and ver.startswith('2'): # Oh Python 2... specs.append('%s >=%s,<3' % (name, ver)) else: specs.append('%s' % name) specs.extend(common.specs_from_args(args.packages, json=args.json)) if command == 'install' and args.revision: get_revision(args.revision, json=args.json) elif not (newenv and args.clone): common.check_specs(prefix, specs, json=args.json, create=(command == 'create')) num_cp = sum(s.endswith('.tar.bz2') for s in args.packages) if num_cp: if num_cp == len(args.packages): depends = misc.install_local_packages(prefix, args.packages, verbose=not args.quiet) if args.no_deps: depends = [] specs = list(set(depends)) args.unknown = True else: common.error_and_exit( "cannot mix specifications with conda package filenames", json=args.json, error_type="ValueError") # handle tar file containing conda packages if len(args.packages) == 1: tar_path = args.packages[0] if tar_path.endswith('.tar'): depends = install_tar(prefix, tar_path, verbose=not args.quiet) if args.no_deps: depends = [] specs = list(set(depends)) args.unknown = True if args.use_local: from conda.fetch import fetch_index from conda.utils import url_path try: from conda_build.config import croot except ImportError: common.error_and_exit( "you need to have 'conda-build >= 1.7.1' installed" " to use the --use-local option", json=args.json, error_type="RuntimeError") # remove the cache such that a refetch is made, # this is necessary because we add the local build repo URL fetch_index.cache = {} if exists(croot): channel_urls = [url_path(croot)] + list(channel_urls) index = common.get_index_trap(channel_urls=channel_urls, prepend=not args.override_channels, use_cache=args.use_index_cache, unknown=args.unknown, json=args.json, offline=args.offline) if newenv and args.clone: if set(args.packages) - set(default_packages): common.error_and_exit('did not expect any arguments for --clone', json=args.json, error_type="ValueError") clone(args.clone, prefix, json=args.json, quiet=args.quiet, index=index) misc.append_env(prefix) misc.touch_nonadmin(prefix) if not args.json: print_activate(args.name if args.name else prefix) return # Don't update packages that are already up-to-date if command == 'update' and not (args.all or args.force): r = Resolve(index) orig_packages = args.packages[:] for name in orig_packages: installed_metadata = [ci.is_linked(prefix, dist) for dist in linked] vers_inst = [dist.rsplit('-', 2)[1] for dist in linked if dist.rsplit('-', 2)[0] == name] build_inst = [m['build_number'] for m in installed_metadata if m['name'] == name] try: assert len(vers_inst) == 1, name assert len(build_inst) == 1, name except AssertionError as e: if args.json: common.exception_and_exit(e, json=True) else: raise pkgs = sorted(r.get_pkgs(MatchSpec(name))) if not pkgs: # Shouldn't happen? continue latest = pkgs[-1] if (latest.version == vers_inst[0] and latest.build_number == build_inst[0]): args.packages.remove(name) if not args.packages: from conda.cli.main_list import print_packages if not args.json: regex = '^(%s)$' % '|'.join(orig_packages) print('# All requested packages already installed.') print_packages(prefix, regex) else: common.stdout_json_success( message='All requested packages already installed.') return if args.force: args.no_deps = True spec_names = set(s.split()[0] for s in specs) if args.no_deps: only_names = spec_names else: only_names = None if not isdir(prefix) and not newenv: if args.mkdir: try: os.makedirs(prefix) except OSError: common.error_and_exit("Error: could not create directory: %s" % prefix, json=args.json, error_type="OSError") else: common.error_and_exit("""\ environment does not exist: %s # # Use 'conda create' to create an environment before installing packages # into it. #""" % prefix, json=args.json, error_type="NoEnvironmentFound") try: if command == 'install' and args.revision: actions = plan.revert_actions(prefix, get_revision(args.revision)) else: with common.json_progress_bars(json=args.json and not args.quiet): actions = plan.install_actions(prefix, index, specs, force=args.force, only_names=only_names, pinned=args.pinned, minimal_hint=args.alt_hint) if args.copy: new_link = [] for pkg in actions["LINK"]: dist, pkgs_dir, lt = inst.split_linkarg(pkg) lt = ci.LINK_COPY new_link.append("%s %s %d" % (dist, pkgs_dir, lt)) actions["LINK"] = new_link except NoPackagesFound as e: error_message = e.args[0] if command == 'update' and args.all: # Packages not found here just means they were installed but # cannot be found any more. Just skip them. if not args.json: print("Warning: %s, skipping" % error_message) else: # Not sure what to do here pass args._skip = getattr(args, '_skip', ['anaconda']) for pkg in e.pkgs: p = pkg.split()[0] if p in args._skip: # Avoid infinite recursion. This can happen if a spec # comes from elsewhere, like --file raise args._skip.append(p) return install(args, parser, command=command) else: packages = {index[fn]['name'] for fn in index} for pkg in e.pkgs: close = get_close_matches(pkg, packages, cutoff=0.7) if close: error_message += ("\n\nDid you mean one of these?" "\n\n %s" % (', '.join(close))) error_message += '\n\nYou can search for this package on anaconda.org with' error_message += '\n\n anaconda search -t conda %s' % pkg if len(e.pkgs) > 1: # Note this currently only happens with dependencies not found error_message += '\n\n (and similarly for the other packages)' if not find_executable('anaconda', include_others=False): error_message += '\n\nYou may need to install the anaconda-client command line client with' error_message += '\n\n conda install anaconda-client' pinned_specs = plan.get_pinned_specs(prefix) if pinned_specs: error_message += "\n\nNote that you have pinned specs in %s:" % join(prefix, 'conda-meta', 'pinned') error_message += "\n\n %r" % pinned_specs common.error_and_exit(error_message, json=args.json) except SystemExit as e: # Unsatisfiable package specifications/no such revision/import error error_type = 'UnsatisfiableSpecifications' if e.args and 'could not import' in e.args[0]: error_type = 'ImportError' common.exception_and_exit(e, json=args.json, newline=True, error_text=False, error_type=error_type) if plan.nothing_to_do(actions): from conda.cli.main_list import print_packages if not args.json: regex = '^(%s)$' % '|'.join(spec_names) print('\n# All requested packages already installed.') print_packages(prefix, regex) else: common.stdout_json_success( message='All requested packages already installed.') return if not args.json: print() print("Package plan for installation in environment %s:" % prefix) plan.display_actions(actions, index) if command in {'install', 'update'}: common.check_write(command, prefix) if not args.json: common.confirm_yn(args) elif args.dry_run: common.stdout_json_success(actions=actions, dry_run=True) sys.exit(0) with common.json_progress_bars(json=args.json and not args.quiet): try: plan.execute_actions(actions, index, verbose=not args.quiet) if not (command == 'update' and args.all): try: with open(join(prefix, 'conda-meta', 'history'), 'a') as f: f.write('# %s specs: %s\n' % (command, specs)) except IOError as e: if e.errno == errno.EACCES: log.debug("Can't write the history file") else: raise except RuntimeError as e: if len(e.args) > 0 and "LOCKERROR" in e.args[0]: error_type = "AlreadyLocked" else: error_type = "RuntimeError" common.exception_and_exit(e, error_type=error_type, json=args.json) except SystemExit as e: common.exception_and_exit(e, json=args.json) if newenv: misc.append_env(prefix) misc.touch_nonadmin(prefix) if not args.json: print_activate(args.name if args.name else prefix) if args.json: common.stdout_json_success(actions=actions)
for instruction, args in plan: if not isinstance(args, (list, tuple)): args = (args,) log.debug(' %s%r' % (instruction, args)) if state['i'] is not None and instruction in progress_cmds: state['i'] += 1 <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD getLogger('progress.update').info((install.name_dist(arg), state['i']-1)) cmd = _commands.get(instruction) ======= ======= >>>>>>> origin/feature/instruction-arguments ======= <<<<<<< HEAD >>>>>>> princeofdarkness76/feature/instruction-arguments ======= >>>>>>> conda/feature/instruction-arguments >>>>>>> princeofdarkness76/conda ======= >>>>>>> origin/feature/instruction-arguments ======= >>>>>>> princeofdarkness76/feature/instruction-arguments