예제 #1
0
    def test_graph_bad_version_to_dot(self):
        expected = (
            ('towel-stuff', 'bacon', 'bacon (<=0.2)'),
            ('grammar', 'bacon', 'truffles (>=1.2)'),
            ('choxie', 'towel-stuff', 'towel-stuff (0.1)'),
            ('banana', 'strawberry', 'strawberry (>=0.5)'),
        )

        dists = []
        for name in self.DISTROS_DIST + self.DISTROS_EGG + self.BAD_EGGS:
            dist = get_distribution(name, use_egg_info=True)
            self.assertNotEqual(dist, None)
            dists.append(dist)

        graph = depgraph.generate_graph(dists)
        buf = StringIO()
        depgraph.graph_to_dot(graph, buf)
        buf.seek(0)
        matches = []
        lines = buf.readlines()
        for line in lines[1:-1]:  # skip the first and the last lines
            if line[-1] == '\n':
                line = line[:-1]
            match = self.EDGE.match(line.strip())
            self.assertIsNot(match, None)
            matches.append(match.groups())

        self.checkLists(matches, expected)
예제 #2
0
    def test_dependent_dists_egg(self):
        dists = []
        for name in self.DISTROS_DIST + self.DISTROS_EGG:
            dist = get_distribution(name, use_egg_info=True)
            self.assertNotEqual(dist, None)
            dists.append(dist)

        choxie, grammar, towel, bacon, banana, strawberry, cheese = dists

        deps = [d.name for d in depgraph.dependent_dists(dists, choxie)]
        self.checkLists([], deps)

        deps = [d.name for d in depgraph.dependent_dists(dists, grammar)]
        self.checkLists([], deps)

        deps = [d.name for d in depgraph.dependent_dists(dists, towel)]
        self.checkLists(['choxie'], deps)

        deps = [d.name for d in depgraph.dependent_dists(dists, bacon)]
        self.checkLists(['choxie', 'towel-stuff', 'grammar'], deps)

        deps = [d.name for d in depgraph.dependent_dists(dists, strawberry)]
        self.checkLists(['banana'], deps)

        deps = [d.name for d in depgraph.dependent_dists(dists, cheese)]
        self.checkLists([], deps)
예제 #3
0
    def test_graph_disconnected_to_dot(self):
        dependencies_expected = (
            ('towel-stuff', 'bacon', 'bacon (<=0.2)'),
            ('grammar', 'bacon', 'truffles (>=1.2)'),
            ('choxie', 'towel-stuff', 'towel-stuff (0.1)'),
            ('banana', 'strawberry', 'strawberry (>=0.5)'),
        )
        disconnected_expected = ('cheese', 'bacon', 'strawberry')

        dists = []
        for name in self.DISTROS_DIST + self.DISTROS_EGG:
            dist = get_distribution(name, use_egg_info=True)
            self.assertNotEqual(dist, None)
            dists.append(dist)

        graph = depgraph.generate_graph(dists)
        buf = StringIO()
        depgraph.graph_to_dot(graph, buf, skip_disconnected=False)
        buf.seek(0)
        lines = buf.readlines()

        dependencies_lines = []
        disconnected_lines = []

        # First sort output lines into dependencies and disconnected lines.
        # We also skip the attribute lines, and don't include the "{" and "}"
        # lines.
        disconnected_active = False
        for line in lines[1:-1]:  # Skip first and last line
            if line.startswith('subgraph disconnected'):
                disconnected_active = True
                continue
            if line.startswith('}') and disconnected_active:
                disconnected_active = False
                continue

            if disconnected_active:
                # Skip the 'label = "Disconnected"', etc. attribute lines.
                if ' = ' not in line:
                    disconnected_lines.append(line)
            else:
                dependencies_lines.append(line)

        dependencies_matches = []
        for line in dependencies_lines:
            if line[-1] == '\n':
                line = line[:-1]
            match = self.EDGE.match(line.strip())
            self.assertIsNot(match, None)
            dependencies_matches.append(match.groups())

        disconnected_matches = []
        for line in disconnected_lines:
            if line[-1] == '\n':
                line = line[:-1]
            line = line.strip('"')
            disconnected_matches.append(line)

        self.checkLists(dependencies_matches, dependencies_expected)
        self.checkLists(disconnected_matches, disconnected_expected)
예제 #4
0
def _metadata(dispatcher, args, **kw):
    opts = _parse_args(args[1:], 'f:', [])
    if opts['args']:
        name = opts['args'][0]
        dist = get_distribution(name, use_egg_info=True)
        if dist is None:
            logger.warning('%r not installed', name)
            return 1
    elif os.path.isfile('setup.cfg'):
        logger.info('searching local dir for metadata')
        dist = Distribution()  # XXX use config module
        dist.parse_config_files()
    else:
        logger.warning('no argument given and no local setup.cfg found')
        return 1

    metadata = dist.metadata

    if 'f' in opts:
        keys = (k for k in opts['f'] if k in metadata)
    else:
        keys = metadata.keys()

    for key in keys:
        if key in metadata:
            print(metadata._convert_name(key) + ':')
            value = metadata[key]
            if isinstance(value, list):
                for v in value:
                    print('   ', v)
            else:
                print('   ', value.replace('\n', '\n    '))
예제 #5
0
    def test_repr(self):
        dists = []
        for name in self.DISTROS_DIST + self.DISTROS_EGG + self.BAD_EGGS:
            dist = get_distribution(name, use_egg_info=True)
            self.assertNotEqual(dist, None)
            dists.append(dist)

        graph = depgraph.generate_graph(dists)
        self.assertTrue(repr(graph))
예제 #6
0
def _run_packaging_install(path):
    # XXX check for a valid setup.cfg?
    dist = Distribution()
    dist.parse_config_files()
    try:
        dist.run_command('install_dist')
        name = dist.metadata['Name']
        return database.get_distribution(name) is not None
    except (IOError, os.error, PackagingError, CCompilerError) as msg:
        raise ValueError("Failed to install, " + str(msg))
예제 #7
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))
예제 #8
0
 def finalize_options(self):
     self.build_lib = self.get_finalized_command("build").build_lib
     for requirement in self.tests_require:
         if get_distribution(requirement) is None:
             logger.warning("test dependency %s is not installed, "
                            "tests may fail", requirement)
     if (not self.suite and not self.runner and
         self.get_ut_with_discovery() is None):
         raise PackagingOptionError(
             "no test discovery available, please give a 'suite' or "
             "'runner' option or install unittest2")
예제 #9
0
    def test_dependent_dists(self):
        dists = []
        for name in self.DISTROS_DIST:
            dist = get_distribution(name)
            self.assertNotEqual(dist, None)
            dists.append(dist)

        choxie, grammar, towel = dists

        deps = [d.name for d in depgraph.dependent_dists(dists, choxie)]
        self.checkLists([], deps)

        deps = [d.name for d in depgraph.dependent_dists(dists, grammar)]
        self.checkLists([], deps)

        deps = [d.name for d in depgraph.dependent_dists(dists, towel)]
        self.checkLists(['choxie'], deps)
예제 #10
0
    def test_generate_graph_egg(self):
        dists = []
        for name in self.DISTROS_DIST + self.DISTROS_EGG:
            dist = get_distribution(name, use_egg_info=True)
            self.assertNotEqual(dist, None)
            dists.append(dist)

        choxie, grammar, towel, bacon, banana, strawberry, cheese = dists

        graph = depgraph.generate_graph(dists)

        deps = [(x.name, y) for x, y in graph.adjacency_list[choxie]]
        self.checkLists([('towel-stuff', 'towel-stuff (0.1)')], deps)
        self.assertIn(choxie, graph.reverse_list[towel])
        self.checkLists(graph.missing[choxie], ['nut'])

        deps = [(x.name, y) for x, y in graph.adjacency_list[grammar]]
        self.checkLists([('bacon', 'truffles (>=1.2)')], deps)
        self.checkLists(graph.missing[grammar], [])
        self.assertIn(grammar, graph.reverse_list[bacon])

        deps = [(x.name, y) for x, y in graph.adjacency_list[towel]]
        self.checkLists([('bacon', 'bacon (<=0.2)')], deps)
        self.checkLists(graph.missing[towel], [])
        self.assertIn(towel, graph.reverse_list[bacon])

        deps = [(x.name, y) for x, y in graph.adjacency_list[bacon]]
        self.checkLists([], deps)
        self.checkLists(graph.missing[bacon], [])

        deps = [(x.name, y) for x, y in graph.adjacency_list[banana]]
        self.checkLists([('strawberry', 'strawberry (>=0.5)')], deps)
        self.checkLists(graph.missing[banana], [])
        self.assertIn(banana, graph.reverse_list[strawberry])

        deps = [(x.name, y) for x, y in graph.adjacency_list[strawberry]]
        self.checkLists([], deps)
        self.checkLists(graph.missing[strawberry], [])

        deps = [(x.name, y) for x, y in graph.adjacency_list[cheese]]
        self.checkLists([], deps)
        self.checkLists(graph.missing[cheese], [])
예제 #11
0
    def test_generate_graph(self):
        dists = []
        for name in self.DISTROS_DIST:
            dist = get_distribution(name)
            self.assertNotEqual(dist, None)
            dists.append(dist)

        choxie, grammar, towel = dists

        graph = depgraph.generate_graph(dists)

        deps = [(x.name, y) for x, y in graph.adjacency_list[choxie]]
        self.checkLists([('towel-stuff', 'towel-stuff (0.1)')], deps)
        self.assertIn(choxie, graph.reverse_list[towel])
        self.checkLists(graph.missing[choxie], ['nut'])

        deps = [(x.name, y) for x, y in graph.adjacency_list[grammar]]
        self.checkLists([], deps)
        self.checkLists(graph.missing[grammar], ['truffles (>=1.2)'])

        deps = [(x.name, y) for x, y in graph.adjacency_list[towel]]
        self.checkLists([], deps)
        self.checkLists(graph.missing[towel], ['bacon (<=0.2)'])
예제 #12
0
def remove(project_name, paths=None, auto_confirm=True):
    """Removes a single project from the installation.

    Returns True on success
    """
    dist = get_distribution(project_name, use_egg_info=True, paths=paths)
    if dist is None:
        raise PackagingError('Distribution %r not found' % project_name)
    files = dist.list_installed_files(local=True)
    rmdirs = []
    rmfiles = []
    tmp = tempfile.mkdtemp(prefix=project_name + '-uninstall')

    def _move_file(source, target):
        try:
            os.rename(source, target)
        except OSError as err:
            return err
        return None

    success = True
    error = None
    try:
        for file_, md5, size in files:
            if os.path.isfile(file_):
                dirname, filename = os.path.split(file_)
                tmpfile = os.path.join(tmp, filename)
                try:
                    error = _move_file(file_, tmpfile)
                    if error is not None:
                        success = False
                        break
                finally:
                    if not os.path.isfile(file_):
                        os.rename(tmpfile, file_)
                if file_ not in rmfiles:
                    rmfiles.append(file_)
                if dirname not in rmdirs:
                    rmdirs.append(dirname)
    finally:
        shutil.rmtree(tmp)

    if not success:
        logger.info('%r cannot be removed.', project_name)
        logger.info('Error: %s', error)
        return False

    logger.info('Removing %r: ', project_name)

    for file_ in rmfiles:
        logger.info('  %s', file_)

    # Taken from the pip project
    if auto_confirm:
        response = 'y'
    else:
        response = ask('Proceed (y/n)? ', ('y', 'n'))

    if response == 'y':
        file_count = 0
        for file_ in rmfiles:
            os.remove(file_)
            file_count += 1

        dir_count = 0
        for dirname in rmdirs:
            if not os.path.exists(dirname):
                # could
                continue

            files_count = 0
            for root, dir, files in os.walk(dirname):
                files_count += len(files)

            if files_count > 0:
                # XXX Warning
                continue

            # empty dirs with only empty dirs
            if os.stat(dirname).st_mode & stat.S_IWUSR:
                # XXX Add a callable in shutil.rmtree to count
                # the number of deleted elements
                shutil.rmtree(dirname)
                dir_count += 1

        # removing the top path
        # XXX count it ?
        if os.path.exists(dist.path):
            shutil.rmtree(dist.path)

        logger.info('Success: removed %d files and %d dirs',
                    file_count, dir_count)

    return True
예제 #13
0
    def test_get_distribution(self):
        # Test for looking up a distribution by name.
        # Test the lookup of the towel-stuff distribution
        name = 'towel-stuff'  # Note: This is different from the directory name

        # Lookup the distribution
        dist = get_distribution(name)
        self.assertIsInstance(dist, Distribution)
        self.assertEqual(dist.name, name)

        # Verify that an unknown distribution returns None
        self.assertIsNone(get_distribution('bogus'))

        # Verify partial name matching doesn't work
        self.assertIsNone(get_distribution('towel'))

        # Verify that it does not find egg-info distributions, when not
        # instructed to
        self.assertIsNone(get_distribution('bacon'))
        self.assertIsNone(get_distribution('cheese'))
        self.assertIsNone(get_distribution('strawberry'))
        self.assertIsNone(get_distribution('banana'))

        # Now check that it works well in both situations, when egg-info
        # is a file and directory respectively.
        dist = get_distribution('cheese', use_egg_info=True)
        self.assertIsInstance(dist, EggInfoDistribution)
        self.assertEqual(dist.name, 'cheese')

        dist = get_distribution('bacon', use_egg_info=True)
        self.assertIsInstance(dist, EggInfoDistribution)
        self.assertEqual(dist.name, 'bacon')

        dist = get_distribution('banana', use_egg_info=True)
        self.assertIsInstance(dist, EggInfoDistribution)
        self.assertEqual(dist.name, 'banana')

        dist = get_distribution('strawberry', use_egg_info=True)
        self.assertIsInstance(dist, EggInfoDistribution)
        self.assertEqual(dist.name, 'strawberry')