diff options
Diffstat (limited to 'pkgtools/pkgdepgraph')
-rw-r--r-- | pkgtools/pkgdepgraph/INSTALL | 28 | ||||
-rw-r--r-- | pkgtools/pkgdepgraph/Makefile | 10 | ||||
-rw-r--r-- | pkgtools/pkgdepgraph/files/pkgdepgraph.1 | 55 | ||||
-rwxr-xr-x | pkgtools/pkgdepgraph/files/pkgdepgraph.pl | 142 |
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}})); + } +} |