Exemple #1
0
def draw_networkx_with_pydot(nx_graph, include_third_party=False, outfile=None):
    """ Draws a networkx graph using PyDot.
    """
    log.info("")
    import pydot
    dot_graph = pydot.Dot(graph_type='digraph', suppress_disconnected=False)
    dot_nodes = {}
    for nx_node in nx_graph.nodes_iter():
        if not include_third_party and not is_inhouse_package(nx_node.project_name):
            continue
        dot_node = get_dot_node(nx_node)
        dot_nodes[nx_node] = dot_node
        dot_graph.add_node(dot_node)

    for edge in nx_graph.edges_iter():
        if edge[0] not in dot_nodes or edge[1] not in dot_nodes:
            continue
        dot_graph.add_edge(get_dot_edge(edge, dot_nodes))

    if not outfile:
        tmpdir = tempfile.mkdtemp()
        outfile = os.path.abspath(os.path.join(tmpdir, 'graph.png'))
    # TODO: make neato work for nicer layouts
    #dot_graph.write_png(outfile, prog='neato')
    dot_graph.write_png(outfile)
    webbrowser.open('file://%s' % outfile)
    time.sleep(5)
    if not outfile:
        shutil.rmtree(tmpdir)
 def pre(self, command, output_dir, vars):
     if not is_inhouse_package(vars['package']):
         sys.exit("Error: Package name doesn't start with an company prefix.\n" \
                  "Prefixes are:\n" \
                  "%s" % '\n'.join(CONFIG.namespaces))
     prefix, package = vars['package'].split('.', 1)
     vars['package'] = package
     vars['namespace_package'] = prefix
     vars['project_nodot'] = vars['project'].replace('.', '')
     vars['project_dir'] = vars['project'].replace('.', '/')
Exemple #3
0
def get_dot_node(req):
    """ Get a pydot node object from a networkx node """
    import pydot
    fill_colour = "#cccccc"
    shape = "box"
    if is_inhouse_package(req.project_name):
        fill_colour = "green"
    return pydot.Node(' '.join((str(req.project_name), req._chosen_dist.version)),
                      style="filled",
                      fillcolor=fill_colour,
                      shape=shape)
Exemple #4
0
def draw_networkx_with_pydot(nx_graph, include_third_party=False,
                             outfile=None, show_reqs=False):
    """ Draws a networkx graph using PyDot.

    Parameters
    ----------
    nx_graph: `networkx.DiGraph`
        The requirements graph
    include_third_party: `bool`
        Show third-party packages on the graph
    outfile: `path`
        If set, will save the graph to this path
    show_reqs: `bool`
        If set, will show the graph of requirements instead of the related
        distributions - this more closely mirrors the underlying data.
    """
    import pydot
    dot_graph = pydot.Dot(graph_type='digraph', suppress_disconnected=False)
    dot_nodes = {}
    fn_node = get_dot_dist_node
    fn_edge = get_dot_dist_edge
    if show_reqs:
        fn_node = get_dot_req_node
        fn_edge = get_dot_req_edge

    for nx_node in nx_graph.nodes_iter():
        if (not include_third_party and
            not is_inhouse_package(nx_node.project_name)):
            continue

        # Skip requirements that aren't yet 'installed' - this is only the
        # case mid-way through dependency resolution
        if hasattr(nx_node, '_chosen_dist'):
            dot_node = fn_node(nx_node)
            dot_nodes[nx_node] = dot_node
            dot_graph.add_node(dot_node)

    for edge in nx_graph.edges_iter():
        if edge[0] not in dot_nodes or edge[1] not in dot_nodes:
            continue
        dot_graph.add_edge(fn_edge(edge, dot_nodes))

    if not outfile:
        tmpdir = tempfile.mkdtemp()
        outfile = os.path.abspath(os.path.join(tmpdir, 'graph.png'))
    # TODO: make neato work for nicer layouts
    #dot_graph.write_png(outfile, prog='neato')
    log.info("Rendering graph to {0}".format(outfile))
    dot_graph.write_png(outfile)
    webbrowser.open('file://%s' % outfile)
    time.sleep(5)
    if not outfile:
        shutil.rmtree(tmpdir)
 def pre(self, command, output_dir, pkg_vars):
     if not is_inhouse_package(pkg_vars['project']):
         msg = "Package name doesn't start with an company prefix.\n" \
               "Prefixes are:\n" \
               "%s" % '\n'.join(CONFIG.namespaces)
         sys.exit(msg)
     nss = pkg_vars['namespace_separator']
     prefix, package = pkg_vars['project'].split(
                         pkg_vars['namespace_separator'], 1)
     pkg_vars['package'] = package
     pkg_vars['namespace_package'] = prefix
     pkg_vars['project_nodot'] = pkg_vars['project'].replace(nss, '')
     pkg_vars['project_dotted'] = pkg_vars['project'].replace(nss, '.')
     pkg_vars['project_dir'] = pkg_vars['project'].replace(nss, '/')
Exemple #6
0
def get_dot_req_node(req):
    """ Get a pydot node object from a networkx node that represents the
        requirement and its installed dist
    """
    import pydot
    fill_colour = "#cccccc"
    shape = "box"
    if is_inhouse_package(req.project_name):
        fill_colour = "green"
    if hasattr(req, '_chosen_dist'):
        dist = req._chosen_dist.version
    else:
        dist = ''
    return pydot.Node('{0} ({1})'.format(req, dist),
                      style="filled",
                      fillcolor=fill_colour,
                      shape=shape)
Exemple #7
0
def components_command(plat, ns):
    platforms = plat.get_platform_packages()
    if ns.package not in platforms:
        raise PlatError("Package %s is not a platform package" % ns.package)

    pkg_info = plat.get_installed_version(ns.package)
    if not pkg_info:
        raise PlatError("Package %s is not installed" % ns.package)

    meta = plat.get_package_metadata(ns.package, pkg_info.version)
    platform = "%s (%s): %s" % (ns.package, pkg_info.version,
               meta.get("summary", ""))
    statusmsg(platform)

    components = plat.get_package_dependencies(ns.package).itervalues()
    components = ["%s (%s)" % (pkg.name, pkg.version) for pkg in components
                               if pkg and manage.is_inhouse_package(pkg.name)]
    components.sort()
    for component in components:
        statusmsg("    " + component)
Exemple #8
0
    def write_all_revisions(self):
        """ Create ``allrevisions.txt`` file containing subversion revision
            of every project upon which we depend. This won't have the
            dependencies in it if we've not yet been set-up with
            'setup.py develop' or similar.
        """
        my_dist = dependency.get_dist(self.distribution.metadata.name)

        revisions = []  # list of (name,version,url,rev) tuples

        revisions.append((self.distribution.metadata.get_name(),
                          self.distribution.metadata.get_version(),
                          self.full_url,
                          self.revision))

        # get all our requirements
        all_requires = []
        if my_dist:
            my_require = my_dist.as_requirement()
            try:
                all_requires = pkg_resources.working_set.resolve([my_require])
            except (pkg_resources.DistributionNotFound,
                    pkg_resources.VersionConflict):
                # not installed yet -- will probably be OK when we're
                # called after the build has taken place.
                pass

        for dist in all_requires:
            if dist == my_dist or not is_inhouse_package(dist.project_name):
                continue
            rev_data = self.read_all_revisions(dist)  # (name,version,url,rev)
            if rev_data:
                revisions.append(rev_data)

        data = ['# These are the VCS revision numbers used for this particular',
                '# build. This file can be used by release tools to tag a',
                '# working build.']
        for rev_data in revisions:
            data.append(','.join([str(e) for e in rev_data]))
        self.write_file("all revisions", self.all_revisions_file,
                        '\n'.join(data))
Exemple #9
0
def draw_networkx_with_d3(nx_graph, include_third_party=False, outfile=None):
    """ Draws a networkx graph using d3.
    """
    from path import path
    tmpl = string.Template((path(__file__).parent / 'd3' / 'fbl.html').text())

    nodes = {}
    edges = []

    i = 0
    for req in nx_graph.nodes_iter():
        if (not include_third_party and
            not is_inhouse_package(req.project_name)):
            continue
        #print "Node %d: %s" % (i, req.project_name)
        nodes[req.key] = (i, req.project_name)
        i += 1

    for edge in nx_graph.edges_iter():
        if edge[0].key not in nodes or edge[1].key not in nodes:
            continue
        #print "edge: %s -> %s" % (edge[0].key, edge[1].key)
        #print '{source : %d, target: %d, weight: 1}' % (nodes[edge[0].key][0], nodes[edge[1].key][0])
        edges.append('{source : %d, target: %d, weight: 0.5}' % (nodes[edge[0].key][0], nodes[edge[1].key][0]))

    nodes = ',\n'.join(['{label: "%s"}' % i[1] for i in sorted(nodes.values(), key=operator.itemgetter(0))])
    edges = ',\n'.join(edges)

    if not outfile:
        tmpdir = path(tempfile.mkdtemp())
        outfile = tmpdir / 'graph.html'
    else:
        outfile = path(outfile)
    outfile.write_text(tmpl.safe_substitute(nodes=nodes, links=edges))
    webbrowser.open('file://%s' % outfile)
    time.sleep(5)
    if not outfile:
        shutil.rmtree(tmpdir)
Exemple #10
0
 def get_version_comparitor(self, requirement):
     """ Here we pick between 'dev' or 'final' versions.
         We want to use different logic depending on if this is a
         third-party or in-house package:
           In-house-packages: we usually want the latest dev version as
                              keeping on head revisions is sensible to stop
                              code going stale
           Third-party: we usually want the latest final version to protect
                        ourselves from OSS developers exposing their
                        latest untested code to the internet at large.
         To override this logic the packager needs to specify an explicit
         version pin in install_requires or similar for third-party
         packages, or use the prefer-final setup flag for in-house packages.
     """
     if manage.is_inhouse_package(requirement.project_name):
         if self._prefer_final:
             log.debug('  in-house package, prefer-final')
             return easy_install._final_version
         else:
             log.debug('  in-house package, prefer-dev')
             return self.is_dev_version
     else:
         log.debug('  third-party package, always prefer-final')
         return easy_install._final_version
def test_is_inhouse_package():
    with mock.patch.object(manage, 'CONFIG', TEST_CONFIG):
        assert manage.is_inhouse_package('acme.foo')
        assert not manage.is_inhouse_package('foo')
Exemple #12
0
    def _obtain(self, requirement, source=None):
        """ Copy in and override the installer's obtain method to modify the
            following behavior:
             - allow us to differentiate between third-party and in-house
               packages when applying the prefer-final / prefer-dev logic
        """
        # Look at zc.buildout source for comments on this logic
        index = self._index
        if index.obtain(requirement) is None:
            return None
        dists = [dist for dist in index[requirement.project_name] if (
                    dist in requirement and (
                        dist.location not in self._site_packages or
                        self.allow_site_package_egg(dist.project_name))
                    and (
                        (not source) or
                        (dist.precedence == pkg_resources.SOURCE_DIST))
                    )
                 ]

        # Here we pick between 'dev' or 'final' versions.
        # We want to use different logic depending on if this is a third-party
        # or in-house package:
        #  In-house-packages: we usually want the latest dev version as keeping
        #                     on head revisions is sensible to stop code
        #                     going stale
        #  Third-party: we usually want the latest final version to protect
        #               ourselves from OSS developers exposing their
        #               latest untested code to the intenet at large.
        # To overridde this logic the packager needs to specify an explicit
        # version pin in install_requires or similar for third-party packages,
        # or use the prefer-final setup flag for in-house packages.

        # If we prefer final dists, filter for final and use the
        # result if it is non empty.

        if manage.is_inhouse_package(requirement.project_name):
            if self._prefer_final:
                log.debug('  in-house package, prefer-final')
                version_comparitor = easy_install._final_version
            else:
                log.debug('  in-house package, prefer-dev')
                version_comparitor = self.is_dev_version
        else:
            log.debug('  third-party package, always prefer-final')
            version_comparitor = easy_install._final_version

        filtered_dists = [dist for dist in dists
                          if version_comparitor(dist.parsed_version)]
        if filtered_dists:
            log.debug('  filtered to {0}'.format(filtered_dists))
            dists = filtered_dists

        # The rest of this logic is as-is from buildout
        best = []
        bestv = ()
        for dist in dists:
            distv = dist.parsed_version
            if distv > bestv:
                best = [dist]
                bestv = distv
            elif distv == bestv:
                best.append(dist)

        log.debug('  best picks are {0}'.format(best))

        if not best:
            return None
        if len(best) == 1:
            return best[0]
        if self._download_cache:
            for dist in best:
                if (easy_install.realpath(os.path.dirname(dist.location)) ==
                    self._download_cache):
                    return dist
        best.sort()
        return best[-1]
def test_is_inhouse_package():
    with mock.patch.object(manage, 'CONFIG', config.OrganisationConfig(namespaces=['acme'])):
        assert manage.is_inhouse_package('acme.foo')
        assert not manage.is_inhouse_package('foo')