Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 10 Feb 2004 16:38:37 +0100
From:      Stefan Walter <sw@gegenunendlich.de>
To:        Chris BeHanna <chris@behanna.org>
Cc:        ports@freebsd.org
Subject:   Re: Managing ports and their dependencies.
Message-ID:  <20040210153837.GA5296@kyuzo.dunkelkammer.void>
In-Reply-To: <200312070124.46973.chris@behanna.org>
References:  <20031206181534.GE31053@genius.tao.org.uk> <200312070124.46973.chris@behanna.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--MW5yreqqjyrRcusr
Content-Type: multipart/mixed; boundary="3V7upXqbjpZ4EhLz"
Content-Disposition: inline


--3V7upXqbjpZ4EhLz
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

A while ago on ports@freebsd.org:

Chris BeHanna, 07.12.03, 07:24h CET:

> On Saturday 06 December 2003 13:15, Josef Karthauser wrote:
> > I've got loads and loads of ports installed on my box, most of which I
> > probably don't use, but I've no idea which ones these are.  Things like
> > kde install lots of dependancies, and so I've no idea just by looking at
> > the installed port names which ones I need and which ones I don't need.
> >
> > It should be possible to display ports and their dependancies as a
> > connected graph, and then the ports that appear on the leaves of the
> > tree would be the ones that I can consider removing.
> >
> > Does anyone have any code for doing something like this?  I thought
> > I'd ask before I started knocking it up myself.
>=20
>     I started out trying to do this with p5-GraphViz, but the result
> was an unreadable mess.
>=20
>     I'll attach what I have, which I intended to submit as a port
> someday, but it's not ready for that just now.

I thought I'd let you know I did something similar last week, partly
inspired by your mail. It displays the dependency graph of a single
package only, though, not of all installed ones. But even that is too
much to be really useful for ports with more than a couple of
dependencies, as the package database stores indirect dependencies as
well as direct ones, so you end up with a lot of edges that shouldn't be
there. See [1] and [2] for examples. You'd have to use information
directly from the ports to get the correct graph, but the versions in
the ports tree don't necessarily reflect what's installed on your
system...

My variant of the script is attached to this mail.

Stefan

[1]: http://www.gegenunendlich.de/stuff/depgraph-XFree86.ps
[2]: http://www.gegenunendlich.de/stuff/depgraph-mozilla-firebird.ps

--3V7upXqbjpZ4EhLz
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=pkg_depgraph
Content-Transfer-Encoding: quoted-printable

#!/usr/bin/perl
#
# Copyright (c) 2004 Stefan Walter <sw@gegenunendlich.de>
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#

# Visualize the dependency graph for a given installed package.
#
# Syntax: pkg_depgraph <package> [output file]
# Parameters:
#   package    : name of the package
#   output file: output file name (default: depgraph.png)

use strict;
use GraphViz;

my $dbdir =3D "/var/db/pkg";
my $outputfile =3D "depgraph.ps";
my (%packages, %added_pkgs);
my $graph;
my $target_pkg;

#
# Add a new package and those it depends on into graph (recursively)
# Parameter: new package (String)
#
sub add_pkg {
	my $cur_node =3D shift;
=09
	# Add this package as a node
	$graph->add_node($cur_node);
	# Add it to our list of existing nodes
	$added_pkgs{$cur_node} =3D 1;

	# Find packages that list this one in their +REQUIRED_BY
	PKG: foreach my $pkg (sort keys %packages) {
		foreach my $reqitem (@{$packages{$pkg}}) {
			# Does $cur_node depend on $pkg?
			if ($reqitem eq $cur_node) {
				# Did we already add a node for $pkg?
				if (not defined($added_pkgs{$pkg})) {
					add_pkg($pkg);
				}
				# Add an edge for this dependency
				$graph->add_edge($cur_node =3D> $pkg);
				next PKG;
			}
		} # $reqitem
	} # PKG
}

# Examine command line arguments
if (scalar(@ARGV) =3D=3D 1) {
	$target_pkg =3D shift(@ARGV);
}
elsif (scalar(@ARGV) =3D=3D 2) {
	$target_pkg =3D shift(@ARGV);
	$outputfile =3D shift(@ARGV);
}
else {
	print STDERR "Usage: $0 <package> [output file]\n";
	exit(1);
}

# Create a hash (name =3D> reqlist) of all packages
opendir(DBDIR, $dbdir)
	or die "Can't open package db directory $dbdir!";
while(defined(my $file =3D readdir(DBDIR))) {
	my $path =3D $dbdir . '/' . $file;
	my $reqlistfile =3D $path . '/+REQUIRED_BY';
	my @reqlist =3D ();
	# Exclude non-directories, "." and ".."
	if (($file ne ".") && ($file ne "..") && (-d $path)) {
		# Read +REQUIRED_BY if it exists and is not empty
		if (-s $reqlistfile) {
			open(REQLIST, $reqlistfile)
				or die "Can't open $reqlistfile!";
			while (<REQLIST>) {
				# Removing trailing '\n'...
				chomp;
				# ...also prevents empty lines from being added here
				push @reqlist, $_;
			}
			close(REQLIST);
		}
		$packages{$file} =3D [@reqlist];
	}
}
closedir(DBDIR);

# Check if the given package really exists
if (not defined($packages{$target_pkg})) {
	print STDERR "Package '$target_pkg' does not exist!\n";
	exit(1);
}

# Start building the dependency graph with the given package
$graph =3D GraphViz->new(rankdir =3D> 1, concentrate =3D> 1);
add_pkg($target_pkg);

$graph->as_ps($outputfile);

--3V7upXqbjpZ4EhLz--

--MW5yreqqjyrRcusr
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (FreeBSD)

iQGVAwUBQCj6/VaRERsSueCzAQKbFwwAqNpNjgK3hWW8uDAUH4MFvlDRQqNzZPKC
2yxkJK0xU56rr7gkxhePpPHe0G5PQqDKwbrgW4hi7a3Z8sYV26PZKKY6VnAvjgXp
EMofyplnjHNDQCLgwhkEJHrHVMQ28R4h0Mg6KoznysPVMpJM0vSZ1I2evu7befXG
2OasLN+t6jagIo8B4iQOoBPFvVKfRbpgJ2HqQ0422q3CsNdkkxMK9Ib+SmhekYsm
eGlLDSDGu0U3Zldx+cEPDgoQpDEb3yWU2HA57s2zdB5Z5/u5sr71CSCQVmOh15J7
0zMXI5HwwcSJs4caIC8VA7tonOCy2uJ6QyOfeZwFSqqeMKNh5qWy77F+msn+0j+H
RVXmKfrjIdi0VASC8ArkeGWlVmxdcqeVxFipaXyEb3uh0M8fKWZH8BxY7AaMplCN
UvwYpvRWNIuTxY/ubqtAwkhJLRTR6TSL/EEZmxn1f5qvHOdq3E0lzf12dEScTxMh
TlXv7vvdFNmNMxKVwFONOCAqDBTmxp4w
=Lemh
-----END PGP SIGNATURE-----

--MW5yreqqjyrRcusr--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040210153837.GA5296>