summaryrefslogtreecommitdiff
path: root/pkgtools/pkgdepgraph
diff options
context:
space:
mode:
authoratatat <atatat>2002-12-26 05:40:48 +0000
committeratatat <atatat>2002-12-26 05:40:48 +0000
commitb740a258553509286f4822df90f13ca00b00b7e3 (patch)
tree55a4c08a173f20120400736981593876a60f6ffc /pkgtools/pkgdepgraph
parent495d7436684e78586f68f9ab2556fd741e41f941 (diff)
downloadpkgsrc-b740a258553509286f4822df90f13ca00b00b7e3.tar.gz
Upgrade pkgdepgraph to 1.1. New features are:
(1) Graph recoloring, so that as you delete and rebuild bunches of packages, you can see how far along you are (I use this a *lot*). (2) Subgraph grouping (based on work done by David Maxwell) which clusters groups of packages with common prefixes in their names inside a box. (3) The explicit dependency on the graphviz pkg has been removed so that pkgdepgraph can be run on "client machines" that only wish to generate graph data, not to view it (ie, machines that have packages installed but which do not wish to incur the overhead of X or the other stuff that graphviz requires). The fact that you should install graphviz *somewhere* so that you can view the data is noted by the new INSTALL script. Some useless comments have also been removed.
Diffstat (limited to 'pkgtools/pkgdepgraph')
-rw-r--r--pkgtools/pkgdepgraph/INSTALL28
-rw-r--r--pkgtools/pkgdepgraph/Makefile10
-rw-r--r--pkgtools/pkgdepgraph/files/pkgdepgraph.155
-rwxr-xr-xpkgtools/pkgdepgraph/files/pkgdepgraph.pl142
4 files changed, 191 insertions, 44 deletions
diff --git a/pkgtools/pkgdepgraph/INSTALL b/pkgtools/pkgdepgraph/INSTALL
new file mode 100644
index 00000000000..c733f8fa772
--- /dev/null
+++ b/pkgtools/pkgdepgraph/INSTALL
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# $NetBSD: INSTALL,v 1.1 2002/12/26 05:40:48 atatat Exp $
+
+PKGNAME=$1
+STAGE=$2
+
+case ${STAGE} in
+PRE-INSTALL)
+ ;;
+
+POST-INSTALL)
+ echo "============================================================"
+ echo "Note that in order to facilitate the use of this package"
+ echo "on "\""client machines"\"", the dependency of this package upon"
+ echo "the "\""graphviz"\"" package (located in graphics/graphviz) has"
+ echo "been removed. You must install the "\""graphviz"\"" package in"
+ echo "order to view the data that this program generates."
+ echo "============================================================"
+ ;;
+
+*)
+ echo "Unexpected argument: ${STAGE}"
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/pkgtools/pkgdepgraph/Makefile b/pkgtools/pkgdepgraph/Makefile
index 650af1b54d6..d978178dc08 100644
--- a/pkgtools/pkgdepgraph/Makefile
+++ b/pkgtools/pkgdepgraph/Makefile
@@ -1,7 +1,7 @@
-# $NetBSD: Makefile,v 1.1.1.1 2002/11/07 23:18:01 atatat Exp $
+# $NetBSD: Makefile,v 1.2 2002/12/26 05:40:48 atatat Exp $
#
-DISTNAME= pkgdepgraph-1.0
+DISTNAME= pkgdepgraph-1.1
CATEGORIES= pkgtools devel
MASTER_SITES= # empty
DISTFILES= # empty
@@ -10,7 +10,8 @@ MAINTAINER= atatat@netbsd.org
HOMEPAGE= ftp://ftp.netbsd.org/pub/NetBSD/packages/pkgsrc/Packages.txt
COMMENT= Visual representation of installed NetBSD packages
-DEPENDS+= graphviz-[0-9]*:../../graphics/graphviz
+# removed so that pkgdepgraph can be used on "client" machines -- @@@
+# DEPENDS+= graphviz-[0-9]*:../../graphics/graphviz
USE_PERL5= YES
@@ -54,4 +55,7 @@ do-install:
${INSTALL_MAN} ${WRKSRC}/pkgdepgraph.0 ${PREFIX}/man/cat1
${INSTALL_MAN} ${WRKSRC}/pkgdepgraph.1 ${PREFIX}/man/man1
+post-install:
+ @${SH} ${INSTALL_FILE} ${PKGNAME} POST-INSTALL
+
.include "../../mk/bsd.pkg.mk"
diff --git a/pkgtools/pkgdepgraph/files/pkgdepgraph.1 b/pkgtools/pkgdepgraph/files/pkgdepgraph.1
index e3cb16882e7..854fdff47db 100644
--- a/pkgtools/pkgdepgraph/files/pkgdepgraph.1
+++ b/pkgtools/pkgdepgraph/files/pkgdepgraph.1
@@ -1,4 +1,4 @@
-.\" $NetBSD: pkgdepgraph.1,v 1.1.1.1 2002/11/07 23:18:01 atatat Exp $
+.\" $NetBSD: pkgdepgraph.1,v 1.2 2002/12/26 05:40:48 atatat Exp $
.\"
.\" Copyright (c) 2002 by Andrew Brown <atatat@netbsd.org>
.\" Absolutely no warranty.
@@ -11,8 +11,8 @@
.Sh SYNOPSIS
.Nm
.Op Fl d Ar pkg_dbdir
-.Op Fl clov
-.Op Pa lintpkgsrc output ...
+.Op Fl cglov
+.Op Pa data ...
.Sh DESCRIPTION
.Nm
emits a
@@ -25,13 +25,22 @@ named
and
.Pa +REQUIRED_BY
in order to gather its data.
+.Pp
.Nm
will also read any files passed to it as arguments (or stdin if it
is not connected to a tty), in search of output that resembles that
of either
-.Xr lintpkgsrc 1
-or
-.Xr audit-packages 1 .
+.Xr lintpkgsrc 1 ,
+.Xr audit-packages 1 ,
+or the output from a previous incantation of this program.
+.Pp
+In the latter case,
+.Nm
+will recolor the graph passed as input based, as usual, on information
+about currently installed pkgs.
+Packages that are in the input graph, but not currently installed,
+will be colored black, those that are installed will be colored green,
+and those that remain out of date for some reason will remain red.
.Pp
The options are as follows:
.Bl -tag -width indent
@@ -54,6 +63,16 @@ The package is out of date or has had a security advisory issued
against it, and should be replaced.
.It purple
The package was not found in the local pkgsrc tree.
+.It blue
+The package depends on something not found in the local pkgsrc tree.
+.It black
+The package has been removed and not yet replaced, or the graph is
+uncolored.
+The difference between an uncolored graph and a graph that has been
+recolored almost entirely black as a result of removing all the
+packages can be visually detected by the presence of the
+.Nm
+package.
.El
.It Fl d Ar pkg_dbdir
The location of the package database files.
@@ -61,6 +80,14 @@ This defaults to the value of the
.Pa PKG_DBDIR
environment variable, if it is set, or to
.Pa @PKG_DBDIR@ .
+.It Fl g
+Add package subgraph groupings.
+This places all packages with a common prefix (eg
+.Dq p5
+or
+.Dq gimp )
+in a subgraph with a line around it so you can visually associate
+packages.
.It Fl l
Adds package
.Dq location
@@ -101,21 +128,27 @@ To subsequently generate a graph of just the out-of-date nodes as a
gif:
.Bd -literal -offset indent
$ grep -v green pkgdepgraph.dot | \\
- sed 's/"packages"/"out of date packages"/' | \\
- dot -Tgif \> pkgdepgraph.ood.gif
+ sed 's/"packages"/"out of date packages"/' \> out-of-date.dot
+$ dot -Tgif out-of-date.dot \> out-of-date.gif
.Ed
.Pp
To make a list of packages that need to be removed in order to bring
all packages up to date:
.Bd -literal -offset indent
-$ grep -v green pkgdepgraph.dot \> out-of-date
-$ grep label out-of-date | \\
+$ grep label out-of-date.dot | \\
sort -t\\# +1n | \\
sed 's/\\(.\\)".*/\\1/;s/"//' \> delete_order
-$ grep LEAF out-of-date | \\
+$ grep LEAF out-of-date.dot | \\
sort -t\\# +1nr | \\
sed 's/.*label="//;s/\\\\.*//' \> rebuild_order
.Ed
+.Pp
+To see the current state of the installed packages after some packages
+have been deleted, and some (but perhaps not all) have been
+reinstalled:
+.Bd -literal -offset indent
+$ pkgdepgraph out-of-date.dot | dot -Tps \> current.ps
+.Ed
.Sh SEE ALSO
.Xr dot 1 ,
.Xr dotty 1 ,
diff --git a/pkgtools/pkgdepgraph/files/pkgdepgraph.pl b/pkgtools/pkgdepgraph/files/pkgdepgraph.pl
index 4dab20f8f56..66884bd081b 100755
--- a/pkgtools/pkgdepgraph/files/pkgdepgraph.pl
+++ b/pkgtools/pkgdepgraph/files/pkgdepgraph.pl
@@ -1,41 +1,44 @@
#!@PREFIX@/bin/perl
-# $NetBSD: pkgdepgraph.pl,v 1.1.1.1 2002/11/07 23:18:01 atatat Exp $
+# $NetBSD: pkgdepgraph.pl,v 1.2 2002/12/26 05:40:48 atatat Exp $
# pkgdepgraph: @DISTVER@
-# (1) lintpkgsrc -i > ! pkgdepgraph.in (optional, adds color)
-# (1a) audit-packages >> pkgdepgraph.in (optional, adds color)
-# (2) ./pkgdepgraph pkgdepgraph.in > ! pkgdepgraph.out (can leave off lint)
-# (3) dotty pkgdepgraph.out (to view it)
-# (4) dot -Tgif pkgdepgraph.out > ! pkgdepgraph.gif
-# (5) file pkgdepgraph.gif (to determine size)
-# (6) dot -Tps pkgdepgraph.out > ! pkgdepgraph.ps
-# (7) pstopnm -stdout -xsize 26332 -ysize 652 pkgdepgraph.ps > ! pkgdepgraph.ppm
-
use strict;
use Getopt::Std;
-my($opts, %opt, $usecolor, $locations, $order, $versions) = ('cd:lov');
+my($opts, %opt, $usecolor, $group, $locations, $order, $versions) = ('cd:glov');
my($pkg_dbdir);
-die("usage: $0 [-d pkg_dbdir] [-clov]\n") if (!getopts($opts, \%opt));
+die("usage: $0 [-d pkg_dbdir] [-cglov]\n") if (!getopts($opts, \%opt));
$usecolor = $opt{c};
$pkg_dbdir = $opt{d} || $ENV{'PKG_DBDIR'} || "/var/db/pkg";
+$group = $opt{g};
$locations = $opt{l};
$order = $opt{o};
$versions = $opt{v};
my(@pkgs, $pkg, $req, %req, @reqs, @rreqs);
+my(%clusters, $closeme);
my(%where, %leaf, $pkgcnt, $num, %num, @num, %ord, @ord, $suffix);
my(%color, $color1, $color2, $ecolor, %vuln);
my(%need, $label);
+my($recolor, @graph);
##
## load out-of-date or security problem list (if given)
##
+$recolor = 0;
if (@ARGV || ! -t) {
$usecolor = 1;
while (<>) {
- if (/^Version mismatch: '(\S+)' (\S+) vs (\S+)/) {
+ if (/^digraph/) {
+ $recolor = 1;
+ @graph = ($_);
+ }
+ elsif ($recolor == 1) {
+ push(@graph, $_);
+ $recolor = 2 if (/^}/);
+ }
+ elsif (/^Version mismatch: '(\S+)' (\S+) vs (\S+)/) {
$color{"$1-$2"} = "red";
$need{"$1-$2"} = "$1-$3";
}
@@ -45,7 +48,6 @@ if (@ARGV || ! -t) {
elsif (/Package (\S+) has a (\S+) vulnerability/) {
$vuln{$1} = $2;
$color{$1} = "red";
- # $1 =~ /(\S+)-([0-9\.]*([a-z]+\d*)?(nb[0-9]*)?)$/i;
}
}
}
@@ -53,8 +55,7 @@ if (@ARGV || ! -t) {
##
## load pkg list
##
-chdir($pkg_dbdir);
-opendir(P, ".") || die("opendir");
+opendir(P, $pkg_dbdir) || die("opendir");
@pkgs = grep(/-/, readdir(P));
closedir(P);
$pkgcnt = @pkgs;
@@ -65,7 +66,7 @@ $pkgcnt = @pkgs;
foreach $pkg (@pkgs) {
$where{$pkg} = $pkg;
$leaf{$pkg} = 1 unless (defined($leaf{$pkg}));
- open(R, "<$pkg/+BUILD_INFO") ||
+ open(R, "<$pkg_dbdir/$pkg/+BUILD_INFO") ||
die("$pkg: +BUILD_INFO: $!\n");
while (<R>) {
if (/^PKGPATH\s*=\s*(\S+)/) {
@@ -74,26 +75,97 @@ foreach $pkg (@pkgs) {
}
}
close(R);
- next if (!open(R, "<$pkg/+REQUIRED_BY"));
+ next if (!open(R, "<$pkg_dbdir/$pkg/+REQUIRED_BY"));
while ($req = <R>) {
chomp($req);
$leaf{$pkg} = 0;
$req{$req}->{$pkg} = 1;
-# print("$req -> $pkg\n");
}
}
##
+## if we're recoloring an existing graph, recolor it now and finish
+##
+if ($recolor) {
+ my(%over, %nver, @label, $ocolor);
+ map({ /(.*)-(.*)/ && ($nver{$1} = $2) } @pkgs);
+
+ foreach (@graph) {
+ # we don't recolor edges
+ ($pkg) = (/\"([^\"]+)\"/);
+ $pkg =~ s/(.*)-(.*)/$1/;
+ $over{$pkg} = $2;
+
+ if (/, EDGE$/) {
+ if (defined($nver{$pkg})) {
+ s/color=\"[^\"]+\"/color=\"green\"/;
+ }
+ else {
+ s/color=\"[^\"]+\"/color=\"black\"/;
+ }
+ }
+
+ elsif (/label/) {
+ s/color=\"([^\"]+)\"/color="NEWCOLOR"/;
+ $ocolor = $1;
+ s/label=\"([^\"]+)\"/label="NEWLABEL"/;
+ $label = $1;
+ if ($nver{$pkg}) {
+ if ($nver{$pkg} ne $over{$pkg} || $ocolor ne "red") {
+ s/NEWCOLOR/green/;
+ }
+ else {
+ s/NEWCOLOR/$ocolor/;
+ }
+
+ @label = split(/\\n/, $label);
+ $label = "";
+
+ # "where" tag
+ if ($label[0] =~ m:/:) {
+ $label .= "\\n" . shift(@label);
+ }
+
+ # installed pkg
+ $label[0] =~ s/(.*$pkg)-\S*$/$1-$nver{$pkg}/ if ($nver{$pkg});
+ $label .= "\\n" . shift(@label);
+
+ # "needed" pkg
+ if ($label[0] =~ /^$pkg-(.*)/) {
+ $label .= "\\n$label[0]" if ($1 ne $nver{$pkg});
+ shift(@label);
+ }
+
+ # there shouldn't be anything left, but...
+ $label .= "\\n" . join("\\n", @label);
+
+ $label =~ s/\\n//;
+ }
+ else {
+ s/NEWCOLOR/black/;
+ }
+ s/NEWLABEL/$label/;
+ }
+ print;
+ }
+ exit(0);
+}
+
+##
## eliminate redundancies by deleting edges that are redundant
##
foreach $pkg (@pkgs) {
@reqs = sort(keys %{$req{$pkg}});
@rreqs = recurse(@reqs);
-# print("$pkg -> (@reqs) -> (@rreqs)\n");
map(delete($req{$pkg}->{$_}), @rreqs);
}
##
+## Create a hash of clusters of package prefixes, with counts
+##
+map({ $a=""; map({ $a .= $_; $clusters{$a}++; } /([^-_]*[-_])/g); } @pkgs);
+
+##
## impose some sort of order on the pkgs by assigning them numbers
## that indicate their height in the graph
##
@@ -101,15 +173,6 @@ foreach $pkg (@pkgs) {
order(1, $pkg);
}
-sub order {
- my($n, @pkgs) = @_;
- my($pkg);
- foreach $pkg (@pkgs) {
- $ord{$pkg} = $n if ($ord{$pkg} <= $n);
- order($n + 1, sort(keys %{$req{$pkg}}));
- }
-}
-
##
## assign each pkg a group number, and count the number of pkgs in
## that group. the higher the number, the earlier we need to assign
@@ -146,9 +209,16 @@ foreach $pkg (sort(bynum @pkgs)) {
}
$suffix = "\t// \#$ord{$pkg}, group $num{$pkg}, $num[$num{$pkg}] members, $pkgcnt pkgs";
$suffix .= ", LEAF" if ($leaf{$pkg});
+ $a = "";
+ foreach ($pkg =~ /([^-_]*[-_])/g) {
+ last if ($clusters{$a .= $_} <= 1 || !$group);
+ printf("subgraph \"cluster_%s\" {\n", substr($a, 0, -1));
+ $closeme .= "}\n";
+ }
printf("\"%s\" [color=\"%s\",label=\"%s\"];$suffix\n", $pkg , $color1, $label);
+ print($closeme);
+ $closeme = "";
@reqs = sort(keys %{$req{$pkg}});
-# print("// $pkg -> (@reqs)\n");
$suffix =~ s/, LEAF$//;
$suffix .= ", EDGE";
foreach $req (@reqs) {
@@ -226,3 +296,15 @@ sub byord {
return $ord{$b} <=> $ord{$a} ||
$b cmp $a;
}
+
+##
+## order - the order of a pkg is one higher than anything below it
+##
+sub order {
+ my($n, @pkgs) = @_;
+ my($pkg);
+ foreach $pkg (@pkgs) {
+ $ord{$pkg} = $n if ($ord{$pkg} <= $n);
+ order($n + 1, sort(keys %{$req{$pkg}}));
+ }
+}