Beispiel #1
0
def _graph(dispatcher, args, **kw):
    name = args[1]
    dist = get_distribution(name, use_egg_info=True)
    if dist is None:
        logger.warning('Distribution not found.')
        return 1
    else:
        dists = get_distributions(use_egg_info=True)
        graph = generate_graph(dists)
        print(graph.repr_node(dist))
Beispiel #2
0
    def test_get_distributions(self):
        # Lookup all distributions found in the ``sys.path``.
        # This test could potentially pick up other installed distributions
        fake_dists = [('grammar', '1.0a4'), ('choxie', '2.0.0.9'),
                      ('towel-stuff', '0.1'), ('babar', '0.1')]
        found_dists = []

        # Verify the fake dists have been found.
        dists = [dist for dist in get_distributions()]
        for dist in dists:
            self.assertIsInstance(dist, Distribution)
            if (dist.name in dict(fake_dists) and
                dist.path.startswith(self.fake_dists_path)):
                found_dists.append((dist.name, dist.version))
            else:
                # check that it doesn't find anything more than this
                self.assertFalse(dist.path.startswith(self.fake_dists_path))
            # otherwise we don't care what other distributions are found

        # Finally, test that we found all that we were looking for
        self.assertEqual(sorted(found_dists), sorted(fake_dists))

        # Now, test if the egg-info distributions are found correctly as well
        fake_dists += [('bacon', '0.1'), ('cheese', '2.0.2'),
                       ('coconuts-aster', '10.3'),
                       ('banana', '0.4'), ('strawberry', '0.6'),
                       ('truffles', '5.0'), ('nut', 'funkyversion')]
        found_dists = []

        dists = [dist for dist in get_distributions(use_egg_info=True)]
        for dist in dists:
            self.assertIsInstance(dist, (Distribution, EggInfoDistribution))
            if (dist.name in dict(fake_dists) and
                dist.path.startswith(self.fake_dists_path)):
                found_dists.append((dist.name, dist.version))
            else:
                self.assertFalse(dist.path.startswith(self.fake_dists_path))

        self.assertEqual(sorted(fake_dists), sorted(found_dists))
Beispiel #3
0
def main():
    # XXX move to run._graph
    from packaging.database import get_distributions
    tempout = StringIO()
    try:
        old = sys.stderr
        sys.stderr = tempout
        try:
            dists = list(get_distributions(use_egg_info=True))
            graph = generate_graph(dists)
        finally:
            sys.stderr = old
    except Exception as e:
        tempout.seek(0)
        tempout = tempout.read()
        print('Could not generate the graph')
        print(tempout)
        print(e)
        sys.exit(1)

    for dist, reqs in graph.missing.items():
        if len(reqs) > 0:
            print("Warning: Missing dependencies for %r:" % dist.name,
                  ", ".join(reqs))
    # XXX replace with argparse
    if len(sys.argv) == 1:
        print('Dependency graph:')
        print('   ', repr(graph).replace('\n', '\n    '))
        sys.exit(0)
    elif len(sys.argv) > 1 and sys.argv[1] in ('-d', '--dot'):
        if len(sys.argv) > 2:
            filename = sys.argv[2]
        else:
            filename = 'depgraph.dot'

        with open(filename, 'w') as f:
            graph_to_dot(graph, f, True)
        tempout.seek(0)
        tempout = tempout.read()
        print(tempout)
        print('Dot file written at %r' % filename)
        sys.exit(0)
    else:
        print('Supported option: -d [filename]')
        sys.exit(1)
Beispiel #4
0
def _list(dispatcher, args, **kw):
    opts = _parse_args(args[1:], '', [])
    dists = get_distributions(use_egg_info=True)
    if opts['args']:
        results = (d for d in dists if d.name.lower() in opts['args'])
        listall = False
    else:
        results = dists
        listall = True

    number = 0
    for dist in results:
        print('%r %s (from %r)' % (dist.name, dist.version, dist.path))
        number += 1

    if number == 0:
        if listall:
            logger.info('Nothing seems to be installed.')
        else:
            logger.warning('No matching distribution found.')
            return 1
    else:
        logger.info('Found %d projects installed.', number)
Beispiel #5
0
def get_infos(requirements, index=None, installed=None, prefer_final=True):
    """Return the informations on what's going to be installed and upgraded.

    :param requirements: is a *string* containing the requirements for this
                         project (for instance "FooBar 1.1" or "BarBaz (<1.2)")
    :param index: If an index is specified, use this one, otherwise, use
                  :class index.ClientWrapper: to get project metadatas.
    :param installed: a list of already installed distributions.
    :param prefer_final: when picking up the releases, prefer a "final" one
                         over a beta/alpha/etc one.

    The results are returned in a dict, containing all the operations
    needed to install the given requirements::

        >>> get_install_info("FooBar (<=1.2)")
        {'install': [<FooBar 1.1>], 'remove': [], 'conflict': []}

    Conflict contains all the conflicting distributions, if there is a
    conflict.
    """
    # this function does several things:
    # 1. get a release specified by the requirements
    # 2. gather its metadata, using setuptools compatibility if needed
    # 3. compare this tree with what is currently installed on the system,
    #    return the requirements of what is missing
    # 4. do that recursively and merge back the results
    # 5. return a dict containing information about what is needed to install
    #    or remove

    if not installed:
        logger.debug('Reading installed distributions')
        installed = list(get_distributions(use_egg_info=True))

    infos = {'install': [], 'remove': [], 'conflict': []}
    # Is a compatible version of the project already installed ?
    predicate = get_version_predicate(requirements)
    found = False

    # check that the project isn't already installed
    for installed_project in installed:
        # is it a compatible project ?
        if predicate.name.lower() != installed_project.name.lower():
            continue
        found = True
        logger.info('Found %r %s', installed_project.name,
                    installed_project.version)

        # if we already have something installed, check it matches the
        # requirements
        if predicate.match(installed_project.version):
            return infos
        break

    if not found:
        logger.debug('Project not installed')

    if not index:
        index = wrapper.ClientWrapper()

    if not installed:
        installed = get_distributions(use_egg_info=True)

    # Get all the releases that match the requirements
    try:
        release = index.get_release(requirements)
    except (ReleaseNotFound, ProjectNotFound):
        raise InstallationException('Release not found: %r' % requirements)

    if release is None:
        logger.info('Could not find a matching project')
        return infos

    metadata = release.fetch_metadata()

    # we need to build setuptools deps if any
    if 'requires_dist' not in metadata:
        metadata['requires_dist'] = _get_setuptools_deps(release)

    # build the dependency graph with local and required dependencies
    dists = list(installed)
    dists.append(release)
    depgraph = generate_graph(dists)

    # Get what the missing deps are
    dists = depgraph.missing[release]
    if dists:
        logger.info("Missing dependencies found, retrieving metadata")
        # we have missing deps
        for dist in dists:
            _update_infos(infos, get_infos(dist, index, installed))

    # Fill in the infos
    existing = [d for d in installed if d.name == release.name]
    if existing:
        infos['remove'].append(existing[0])
        infos['conflict'].extend(depgraph.reverse_list[existing[0]])
    infos['install'].append(release)
    return infos