From af0c469421434af498b9ca5dfe452232224d4693 Mon Sep 17 00:00:00 2001 From: atatat Date: Thu, 6 Mar 2003 21:13:13 +0000 Subject: Jump to pkgdepgraph v2.0. New features (excerpts from the man page, not in proper order, so that you can better see how it fits together): -L Limit the graph to those packages that are out of date or ulti- mately depend on some package that is. -D Instead of the standard graph output, pkgdepgraph lists the packages that need to be deleted, in ``least required first'' order, so that they can be deleted without any dependency prob- lems. -R Instead of the standard graph output, emits a series of sh(1) commands that will rebuild all the out of date packages by re- building all the deleted leaf packages. -U package Generates a graph with only the out of date dependencies of package marked in red (ie, packages that are out of date but not dependencies of package will not be considered out of date). -f Force a rebuild of all dependent packages. This option is for use in conjunction with the -U option to force a rebuild of all the dependencies of a package to be updated. -O package Marks package as out of date so that you can see the impact of deleting dependent packages and rebuilding everything. -t target Changes the target of the -R output from ``install'' to target in case you want to ``make package'' or some other target. -c Inserts a ``make clean'' command in the set of instructions to rebuild packages (see the -R option) after they are installed. -C Asserts -c and adds ``CLEANDEPENDS=YES'' so that all rebuilt de- pendencies are cleaned as well. The code was also cleaned up a bit, some unused or otherwise useless variables were culled, the "multiple box" phenomenon of subgroups is fixed, and the examples were all cleaned up to take advantage of all the new features. Hey ma! Now I can update my pkgs in four easy steps! $ lintpkgsrc -i > pkgdepgraph.in $ pkgdepgraph -R pkgdepgraph.in > rebuild.sh $ pkg_delete `pkgdepgraph -D pkgdepgraph.in` $ sh rebuild.sh --- pkgtools/pkgdepgraph/INSTALL | 14 ++- pkgtools/pkgdepgraph/Makefile | 8 +- pkgtools/pkgdepgraph/files/pkgdepgraph.1 | 186 ++++++++++++++++++++++++++---- pkgtools/pkgdepgraph/files/pkgdepgraph.pl | 156 +++++++++++++++++++++---- 4 files changed, 306 insertions(+), 58 deletions(-) (limited to 'pkgtools') diff --git a/pkgtools/pkgdepgraph/INSTALL b/pkgtools/pkgdepgraph/INSTALL index c733f8fa772..fb13ad41acb 100644 --- a/pkgtools/pkgdepgraph/INSTALL +++ b/pkgtools/pkgdepgraph/INSTALL @@ -1,6 +1,6 @@ #!/bin/sh # -# $NetBSD: INSTALL,v 1.1 2002/12/26 05:40:48 atatat Exp $ +# $NetBSD: INSTALL,v 1.2 2003/03/06 21:13:13 atatat Exp $ PKGNAME=$1 STAGE=$2 @@ -11,11 +11,13 @@ 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 "Note that in order to facilitate the use of this package on" + echo ""\""client machines"\"", the dependency of this package upon the" + echo ""\""graphviz"\"" package (located in graphics/graphviz) has been" + echo "removed. You must install the "\""graphviz"\"" package in order" + echo "to view the graph data that this program generates, though" + echo "much of the functionality of this program does not require" + echo "you to look at the graphs." echo "============================================================" ;; diff --git a/pkgtools/pkgdepgraph/Makefile b/pkgtools/pkgdepgraph/Makefile index f01280fa02a..5ca69c5a263 100644 --- a/pkgtools/pkgdepgraph/Makefile +++ b/pkgtools/pkgdepgraph/Makefile @@ -1,7 +1,7 @@ -# $NetBSD: Makefile,v 1.4 2003/01/31 12:18:33 abs Exp $ +# $NetBSD: Makefile,v 1.5 2003/03/06 21:13:13 atatat Exp $ # -DISTNAME= pkgdepgraph-1.2 +DISTNAME= pkgdepgraph-2.0 CATEGORIES= pkgtools devel MASTER_SITES= # empty DISTFILES= # empty @@ -20,8 +20,6 @@ WRKSRC= ${WRKDIR} NO_CHECKSUM= yes NO_CONFIGURE= yes -MAKE_ENV= PKG_DBDIR=${PKG_DBDIR:Q} - DISTVER= ${DISTNAME:S/pkgdepgraph-//} .include "../../mk/bsd.prefs.mk" @@ -42,12 +40,14 @@ do-build: .for FILE in pkgdepgraph ${SED} -e 's|@PREFIX@|${PREFIX}|g' \ -e 's|@PKG_DBDIR@|${PKG_DBDIR}|g' \ + -e 's|@PKGSRCDIR@|${_PKGSRCDIR}|g' \ -e 's|@DISTVER@|${DISTVER}|g' \ < ${WRKSRC}/${FILE}.pl \ > ${WRKSRC}/${FILE} .endfor .for FILE in pkgdepgraph ${SED} -e 's|@PKG_DBDIR@|${PKG_DBDIR}|g' \ + -e 's|@PKGSRCDIR@|${_PKGSRCDIR}|g' \ < ${WRKSRC}/${FILE}.1.in \ > ${WRKSRC}/${FILE}.1 ${NROFF} ${WRKSRC}/${FILE}.1 >${WRKSRC}/${FILE}.0 diff --git a/pkgtools/pkgdepgraph/files/pkgdepgraph.1 b/pkgtools/pkgdepgraph/files/pkgdepgraph.1 index b8c9ee3a21f..5d54255a9bb 100644 --- a/pkgtools/pkgdepgraph/files/pkgdepgraph.1 +++ b/pkgtools/pkgdepgraph/files/pkgdepgraph.1 @@ -1,17 +1,21 @@ -.\" $NetBSD: pkgdepgraph.1,v 1.3 2002/12/26 11:12:59 wiz Exp $ +.\" $NetBSD: pkgdepgraph.1,v 1.4 2003/03/06 21:13:13 atatat Exp $ .\" -.\" Copyright (c) 2002 by Andrew Brown +.\" Copyright (c) 2002, 2003 by Andrew Brown .\" Absolutely no warranty. .\" -.Dd November 6, 2002 +.Dd March 6, 2003 .Dt PKGDEPGRAPH 1 .Sh NAME .Nm pkgdepgraph .Nd visual representation of installed packages .Sh SYNOPSIS .Nm +.Op Fl CcDfgLloRv .Op Fl d Ar pkg_dbdir -.Op Fl cglov +.Op Fl O Ar package +.Op Fl P Ar pkgsrcdir +.Op Fl t Ar target +.Op Fl U Ar package .Op Pa data ... .Sh DESCRIPTION .Nm @@ -30,7 +34,8 @@ in order to gather its data. 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 , +.Xr lintpkgsrc 1 +.Fl i , .Xr audit-packages 1 , or the output from a previous incantation of this program. .Pp @@ -42,16 +47,14 @@ 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 -.It Fl c -Use colors. -The graph defaults to black, but if this option is used and the output -from +The graph defaults to black, but if data from .Xr lintpkgsrc 1 +.Fl i or .Pa audit-packages -is given, then nodes (and edges leading from them) will be colored in +is given, or if a specific package is asserted to be out of date (via the +.Fl O +option), then nodes (and edges leading from them) will be colored in the following manner: .Bl -tag -width purple .It green @@ -74,12 +77,47 @@ packages can be visually detected by the presence of the .Nm package. .El +.Pp +The options are as follows: +.Bl -tag -width package +.It Fl C +Asserts +.Fl c +and adds +.Dq CLEANDEPENDS=YES +so that all rebuilt dependencies are cleaned as well. +.It Fl c +Inserts a +.Dq make clean +command in the set of instructions to rebuild packages (see the +.Fl R +option) after they are installed. +The +.Fl c +option used to enable graph coloring, but now graph coloring is done +automatically if any coloring data is given. +.It Fl D +Instead of the standard graph output, +.Nm +lists the packages that need to be deleted, in +.Dq least required first +order, so that they can be deleted without any dependency problems. +This is a good first step to take before rebuilding all your packages +that are out of date (see the +.Fl R +option). .It Fl d Ar pkg_dbdir The location of the package database files. This defaults to the value of the .Pa PKG_DBDIR environment variable, if it is set, or to .Pa @PKG_DBDIR@ . +.It Fl f +Force a rebuild of all dependent packages. +This option is for use in conjunction with the +.Fl U +option to force a rebuild of all the dependencies of a package to be +updated. .It Fl g Add package subgraph groupings. This places all packages with a common prefix (e.g., @@ -88,11 +126,30 @@ or .Dq gimp ) in a subgraph with a line around it so you can visually associate packages. +.It Fl L +Limit the graph to those packages that are out of date +or ultimately depend on some package that is. .It Fl l Adds package .Dq location information to the labels on the nodes. This is the path to the package under the local pkgsrc tree. +.It Fl P Ar pkgsrcdir +The root of the pkgsrc source tree. +This defaults to the value of the +.Pa PKGSRCDIR +environment variable, if it is set, or to +.Pa @PKGSRCDIR@ . +.It Fl O Ar package +Marks +.Ar package +as out of date so that you can see the impact of deleting dependent +packages and rebuilding everything. +This option can be used as a quick alternative to using the output +from +.Xr lintpkgsrc 1 +.Fl i +for graph coloring information. .It Fl o Adds a package .Dq order @@ -102,6 +159,39 @@ that each node has a number greater than that of anything which depends on it, and with the .Dq leaf nodes numbered one. +.It Fl R +Instead of the standard graph output, emits a series of +.Xr sh 1 +commands that will rebuild all the out of date packages by rebuilding +all the deleted leaf packages. +Packages that are out of date should be deleted first (see the +.Fl D +option). +.It Fl t Ar target +Changes the target of the +.Fl R +output from +.Dq install +to +.Ar target +in case you want to +.Dq make package +or some other target. +.It Fl U Ar package +Generates a graph with only the out of date dependencies of +.Ar package +marked in red (ie, packages that are out of date but not dependencies +of +.Ar package +will not be considered out of date). +This will show the entire effect of deleting all related packages in +order to update the dependencies of the given package. +If the +.Fl f +option is used, then all the dependencies of +.Ar package +will be marked as out of date and the effect on the installed package +base will be accordingly greater. .It Fl v Adds the package version number to the node's label in the graph. .El @@ -109,6 +199,9 @@ Adds the package version number to the node's label in the graph. .Ss PKG_DBDIR Where to find registered packages instead of .Pa @PKG_DBDIR@ . +.Ss PKGSRCDIR +Where the pkgsrc tree is located instead of +.Pa @PKGSRCDIR@ . .Sh EXAMPLES The default output: .Bd -literal -offset indent @@ -124,27 +217,72 @@ $ pkgdepgraph -clv pkgdepgraph.in \*[Gt] pkgdepgraph.dot $ dot -Tps pkgdepgraph.dot \*[Gt] pkgdepgraph.ps .Ed .Pp -To subsequently generate a graph of just the out-of-date nodes as a -gif: +To 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"/' \*[Gt] out-of-date.dot +$ pkgdepgraph -L pkgdepgraph.in \*[Gt] out-of-date.dot $ dot -Tgif out-of-date.dot \*[Gt] 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 label out-of-date.dot | \\ - sort -t\\# +1n | \\ - sed 's/\\(.\\)".*/\\1/;s/"//' \*[Gt] delete_order -$ grep LEAF out-of-date.dot | \\ - sort -t\\# +1nr | \\ - sed 's/.*label="//;s/\\\\.*//' \*[Gt] rebuild_order +$ pkgdepgraph -D pkgdepgraph.in \*[Gt] delete_order +$ pkgdepgraph -R pkgdepgraph.in \*[Gt] rebuild.sh +.Ed +.Pp +To subsequently delete all out of date and stale packages: +.Bd -literal -offset indent +$ pkg_delete `cat delete_order` +$ sh rebuild.sh +.Ed +.Pp +The last step will probably take a while, but if you need to stop it +or it stops by itself for any reason, you can rerun the script, and it +will pick up where it left off. +If there are certain packages that you want installed before others +are reinstalled, feel free to reorder the lines in the script. +.Pp +You can also +.Dq make clean +wherever you like when the script is not running, or even update your +tree in between runs of the script, though in the latter case, it +would be prudent to resume the script in the following manner so that +any packages that are newly out of date are removed and replaced. +.Bd -literal -offset indent +$ pkgdepgraph -D pkgdepgraph.in \*[Gt] delete_order +$ pkgdepgraph -R pkgdepgraph.in \*[Gt]\*[Gt] rebuild.sh +$ pkg_delete `cat delete_order` +$ sh rebuild.sh +.Ed +.Pp +It is important to note that if you have specifically installed a +particular package that is a dependency, and another package (or other +packages) exist that can satisfy the same dependency, you should +probably pre-install that particular package. +There is no guarantee that the typical processing order will install +the same package. +.Pp +A similar task is to update all the out of date dependencies of an +package, rebuild the package, and any others that might share the same +dependencies: +.Bd -literal -offset indent +$ pkgdepgraph -U mozilla -D pkgdepgraph.in \*[Gt] delete_order +$ pkgdepgraph -U mozilla -R pkgdepgraph.in \*[Gt] rebuild.sh +$ pkg_delete `cat delete_order` +$ sh rebuild.sh +.Ed +.Pp +Or perhaps to rebuild a specific package and all packages which depend +on it: +.Bd -literal -offset indent +$ pkgdepgraph -O glib -D \*[Gt] delete_order +$ pkgdepgraph -O glib -R \*[Gt] rebuild.sh +$ pkg_delete `cat delete_order` +$ sh rebuild.sh .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 +Finally, 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 \*[Gt] current.ps diff --git a/pkgtools/pkgdepgraph/files/pkgdepgraph.pl b/pkgtools/pkgdepgraph/files/pkgdepgraph.pl index 66884bd081b..5044714b929 100755 --- a/pkgtools/pkgdepgraph/files/pkgdepgraph.pl +++ b/pkgtools/pkgdepgraph/files/pkgdepgraph.pl @@ -1,25 +1,44 @@ #!@PREFIX@/bin/perl -# $NetBSD: pkgdepgraph.pl,v 1.2 2002/12/26 05:40:48 atatat Exp $ +# Copyright (c) 2002, 2003 by Andrew Brown +# Absolutely no warranty. + +# $NetBSD: pkgdepgraph.pl,v 1.3 2003/03/06 21:13:13 atatat Exp $ # pkgdepgraph: @DISTVER@ use strict; use Getopt::Std; -my($opts, %opt, $usecolor, $group, $locations, $order, $versions) = ('cd:glov'); -my($pkg_dbdir); -die("usage: $0 [-d pkg_dbdir] [-cglov]\n") if (!getopts($opts, \%opt)); -$usecolor = $opt{c}; +my($opts, %opt) = ('CcDd:fgLlO:oP:Rt:vU:'); +my($iam, $usecolor, $group, $locations, $order, $versions); +my($limit, $delete, $rebuild, $force, $outofdate, $update, $clean); +my($pkg_dbdir, $pkgsrcdir); + +($iam = $0) =~ s:.*/::; +die("usage: $iam [-CcDfgLloRv] [-d pkg_dbdir] [-O package] [-P pkgsrcdir]\n", + " " x (length($iam) + 8), "[-t target] [-U package] [data ...]\n") + if (!getopts($opts, \%opt)); + +$usecolor = 0; $pkg_dbdir = $opt{d} || $ENV{'PKG_DBDIR'} || "/var/db/pkg"; +$pkgsrcdir = $opt{P} || $ENV{'PKGSRCDIR'} || "/usr/pkgsrc"; $group = $opt{g}; $locations = $opt{l}; $order = $opt{o}; $versions = $opt{v}; +$delete = $opt{D}; +$rebuild = $opt{t} || "install" if (defined($opt{R})); +$force = $opt{f}; +$outofdate = $opt{O}; +$update = $opt{U}; +$limit = $opt{L}; +$clean = $opt{c} ? "clean" : ""; +$clean = $opt{C} ? "CLEANDEPENDS=YES clean" : $clean; 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(%where, $pkgcnt, $num, %num, @num, %ord, @ord, $suffix); +my(%color, $color, %vuln); my(%need, $label); my($recolor, @graph); @@ -65,7 +84,6 @@ $pkgcnt = @pkgs; ## foreach $pkg (@pkgs) { $where{$pkg} = $pkg; - $leaf{$pkg} = 1 unless (defined($leaf{$pkg})); open(R, "<$pkg_dbdir/$pkg/+BUILD_INFO") || die("$pkg: +BUILD_INFO: $!\n"); while () { @@ -78,7 +96,6 @@ foreach $pkg (@pkgs) { next if (!open(R, "<$pkg_dbdir/$pkg/+REQUIRED_BY")); while ($req = ) { chomp($req); - $leaf{$pkg} = 0; $req{$req}->{$pkg} = 1; } } @@ -161,17 +178,16 @@ foreach $pkg (@pkgs) { } ## -## Create a hash of clusters of package prefixes, with counts +## create a hash of clusters of package prefixes, with counts. later, +## clusters that have more than one member can be marked as subgraphs. ## -map({ $a=""; map({ $a .= $_; $clusters{$a}++; } /([^-_]*[-_])/g); } @pkgs); +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 ## -foreach $pkg (@pkgs) { - order(1, $pkg); -} +map(order(1, $_), @pkgs); ## ## assign each pkg a group number, and count the number of pkgs in @@ -192,12 +208,81 @@ foreach $pkg (sort(byord @pkgs)) { $num++; } +## +## if we want to check a specific pkg for rebuild impact... +## +if ($outofdate) { + $usecolor = 1; + $outofdate = canonicalize($outofdate); + + if ($color{$outofdate} ne "red") { + $color{$outofdate} = "red"; + $need{$outofdate} = "$outofdate (forced)"; + } +} + +## +## if we want to update a specific package, mark all non-related +## packages as "green" +## +if ($update) { + $update = canonicalize($update); + + # these things will need to be checked + @reqs = sort(keys %{$req{$update}}); + @rreqs = recurse(@reqs); + + # check each pkg to see if it will be affected + foreach $pkg (@pkgs) { + # these pkgs are dependencies + if (grep($pkg eq $_, ($update, @reqs, @rreqs))) { + if ($force && $color{$pkg} ne "red") { + # we want to force rebuild of *all* dependencies + $color{$pkg} = "red"; + $need{$pkg} = "$pkg (forced)"; + } + } + # these packages do not depend on any of $update's dependencies + else { + delete($color{$pkg}); + delete($need{$pkg}); + } + } +} + +## +## "delete" output, ordered with "least depended on" first +## +if ($delete) { + map(print("$_\n"), + reverse(sort(byord grep(color($_) ne "green", @pkgs)))); + exit(0); +} + +## +## "rebuild" output for sh(1), with just leaves listed +## +if ($rebuild) { + map(printf("( pkg_info -qe %s || " . + "( cd %s/%s && " . + "make %s%s )) &&\n", + ($need{$_} || $_) =~ /(.*)-.*/, + $pkgsrcdir, $where{$_}, + $rebuild, + $clean ? " && make $clean" : ""), + grep(color($_) ne "green" && $ord{$_} == 1, @pkgs)); + print("true\n"); + exit(0); +} + ## ## show left overs as a graph ## -print("digraph \"packages\" {\n"); +printf("digraph \"%s\" {\n", + $limit ? "out of date packages" : "packages"); foreach $pkg (sort(bynum @pkgs)) { - $color1 = color($pkg); + $color = color($pkg); + next if ($limit && $color eq "green"); $label = $pkg; $label =~ s/(.*)-.*/$1/ if (!$versions); $label = "($ord{$pkg}) $label" if ($order); @@ -208,22 +293,28 @@ foreach $pkg (sort(bynum @pkgs)) { $label .= "\\n[$vuln{$pkg}]"; } $suffix = "\t// \#$ord{$pkg}, group $num{$pkg}, $num[$num{$pkg}] members, $pkgcnt pkgs"; - $suffix .= ", LEAF" if ($leaf{$pkg}); + $suffix .= ", LEAF" if ($ord{$pkg} == 1); $a = ""; + $b = 0; foreach ($pkg =~ /([^-_]*[-_])/g) { last if ($clusters{$a .= $_} <= 1 || !$group); + next if ($b && $clusters{$a} >= $b); printf("subgraph \"cluster_%s\" {\n", substr($a, 0, -1)); + $b = $clusters{$a}; $closeme .= "}\n"; } - printf("\"%s\" [color=\"%s\",label=\"%s\"];$suffix\n", $pkg , $color1, $label); + printf("\"%s\" [color=\"%s\",label=\"%s\"];$suffix\n", $pkg, + $usecolor ? $color : "black", $label); print($closeme); $closeme = ""; @reqs = sort(keys %{$req{$pkg}}); $suffix =~ s/, LEAF$//; $suffix .= ", EDGE"; foreach $req (@reqs) { - $color2 = color($req); - printf("\"%s\" -> \"%s\" [color=\"%s\"];$suffix\n", $req, $pkg, $color2); + $color = color($req); + next if ($limit && $color eq "green"); + printf("\"%s\" -> \"%s\" [color=\"%s\"];$suffix\n", $req, $pkg, + $usecolor ? $color : "black"); } } print("}\n"); @@ -241,6 +332,26 @@ sub recurse { sort(keys %list); } +## +## canonicalize a pkg name based on what we have installed +## +sub canonicalize { + my($canon); + my($pkg) = @_; + + # attempt to find actual pkg, first by argument given... + ($canon) = grep($pkg eq $_, @pkgs); + + # ...then by comparing against the internal list sans version numbers + ($canon) = grep(($a = $_) =~ s/(.*)-.*/$1/ && $pkg eq $a, @pkgs) + if (!defined($canon)); + + die("package '$update' not found\n") + if (!defined($canon)); + + $canon; +} + ## ## lowest number of a graph ## @@ -258,10 +369,7 @@ sub number { ## sub color { my($pkg) = @_; - if (! $usecolor) { - "black"; - } - elsif ($color{$pkg}) { + if ($color{$pkg}) { $color{$pkg}; } else { -- cgit v1.2.3