Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Apr 2001 20:28:09 -0400
From:      Kevin Way <kevin.way@overtone.org>
To:        Jeff Kletsky <Jeff+freebsd@wagsky.com>
Cc:        freebsd-stable@freebsd.org
Subject:   Re: pkg/port dependency tool (enclosed)
Message-ID:  <20010424202809.A2026@bean.overtone.org>
In-Reply-To: <Pine.BSF.4.21.0104240708590.5506-100000@wildside.wagsky.com>; from Jeff%2Bfreebsd@wagsky.com on Tue, Apr 24, 2001 at 07:16:25AM -0700
References:  <15076.20167.337195.349137@guru.mired.org> <Pine.BSF.4.21.0104240708590.5506-100000@wildside.wagsky.com>

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

--C7zPtVaVf+AK4Oqc
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Great Work!

Correct me if I'm wrong, but I believe I found one additional gotcha.
It would appear that your script doesn't find build dependancies, as they
don't seem to be recorded anywhere in /var/db/pkg (see www/mod_php4 for
an example).  My apologies if that's what you meant by the third item
in your TODO.

If you would like any assistance in completing your TODO, I'd be more than
willing to help.

	-Kevin

On Tue, Apr 24, 2001 at 07:16:25AM -0700, Jeff Kletsky wrote:
> Thanks to some good pointers, I have an *alpha* of the text-output version
> of the tool available. I need to integrate with the code already in
> pkg_version and resolve how to detect and include the dependencies
> introduced by the USE_* variables. I'll probably be quiet for a while, the
> "easy" part is done -- now to make it a robust tool...
>=20
> Jeff
>=20
> #!/usr/bin/perl -w
>=20
> # $Header: /usr/local/cvsroot/pkg_graph/graph_depends.pl,v 1.4 2001/04/24=
 14:08:28 jeff Exp $
>=20
> #
> # Tool to read from /var/db/pkg to find all pkg/port dependencies
> # create a graph and solve for process to rebuild ports in "proper
> # order"
> #
> # Examples of use:
> #
> # pkg_version -L =3D | cut -f 1 -d " " | graph_depends.pl
> #
> # graph_depends.pl -a
> #
>=20
> # Status: ALPHA development
>=20
> # Author: Jeff Kletsky mailto:jeff+freebsd@wagsky.com
>=20
> #
> # TODO:
> #
> # * use '/usr/sbin/pkg_version'; to access the ports index, tie nodes
> #   to their cannonical names, and ouput code to rebuild ports
> #
> # * deal with the USE_BZIP2 variables that Kevin Way has pointed out
> #
> # * Include dependencies of ports about to be built
> #
> # * Discriminate between existing dependencies and future ones
> #   - How are "orphaned" ports to be handled??
> #
> # * Consider solving the problem where the changes are driven by
> #   wishing to rebuild a target, all its predecessors, and all their
> #   successors (e.g., " I need a clean version of gnome")
> #
>=20
> #
> # Thanks to:
> #
> # * Mike Meyer for mumbling the words "transitive closure of the=20
> #   dependency matrix" and getting this rolling in the right direction
> #=20
> # * Garance Drosihn for providing me to Kevin Way's comments on the=20
> #   USE_ variable issue
> #
>=20
>=20
> use strict;
> use POSIX qw(EXIT_FAILURE EXIT_SUCCESS);
> use FileHandle;
>=20
> require Graph;  # (not yet in the ports tree)
>=20
> my $usage =3D qq(
> Usage:
> $0 [-a]
>=20
> Reads a list of packages/ports to be updated from STDIN and prints a=20
> suggested order for updating those packages/ports based on the dependenci=
es
> seen in the installed list of packages/ports in /var/db/pkg
>=20
>   -a  Ignores STDIN and looks at all registered packages/ports
>=20
> );
>=20
> my $doall =3D 0;
>=20
> if ( $#ARGV > 0 ) {
>     die $usage;
> }
>=20
> if ( $#ARGV =3D=3D 0 ) {
>     $doall =3D ( shift @ARGV eq "-a" );
>     die $usage unless $doall;
> }
>=20
> my $pkg_db_dir =3D '/var/db/pkg';
> $pkg_db_dir =3D~ s/\/$//;             # prevent "trailing-slash" issue
>=20
> my $required_by_filename =3D '+REQUIRED_BY';
>=20
> #
> # Open the directory that contains pkg/port information
> #
>=20
> opendir (VARDBPKG, $pkg_db_dir) or die "Unable to open $pkg_db_dir: $!";
>=20
> #
> # Get the subdirectories, and iterate through them
> #
>=20
> my @installed_pkgs =3D readdir VARDBPKG;
>=20
> die "No files read in $pkg_db_dir\n" unless $#installed_pkgs > 1;
>=20
> #
> # Read the list of files from STDIN
> #
>=20
> my $target;
> my %targets;
>=20
> if ( !$doall ) {
>=20
>     while ( $target =3D <> ) {
> 	chomp $target;
> 	$targets{$target} =3D 'true';
>     }
>=20
> } else {
>=20
>     foreach $target (@installed_pkgs) {
> 	$targets{$target} =3D 'true';
>     }
>=20
> }=09
>=20
> my $pkg;
> my $rqd;
> my $required_by_fqn;
> my $required_by_fh;
>=20
> my $pkg_node;
> my $rqd_node;
>=20
> my $graph =3D new Graph;
> $graph->directed('true');
>=20
>  PKG:
>=20
>     foreach $pkg (sort @installed_pkgs) {
> =09
> =09
> 	next PKG if $pkg =3D~ m/^\./;
>=20
> 	$graph->add_vertex($pkg);
>=20
> =09
> #
> # See if there is a +REQUIRED_BY file, open it, and process lines
> #
> =09
> 	$required_by_fqn =3D "${pkg_db_dir}/${pkg}/${required_by_filename}";
>=20
> 	next PKG unless -e $required_by_fqn;
> =09
> 	$required_by_fh =3D new FileHandle "< $required_by_fqn";
> 	die "Unable to open $required_by_fqn: $!"=20
> 	    unless defined $required_by_fh;
> =09
> 	while ($rqd =3D <$required_by_fh>) {
>=20
> 	    chomp $rqd;
> 	   =20
> 	    $graph->add_edge($pkg,$rqd);
>=20
> 	}
>=20
>     } # PKG
>=20
> #
> # Now that we have the full graph, check for loops
> # Loops should "never" occur or certain ports would be un-buildable   =20
> # It *is* vaguely possible that the dependencies change and create a loop
> # after one of the components in the loop were already built.
> # Since this is a remote possibility, just die...
> #
>=20
> die "Graph loops back on itself, unable to resolve"=20
>     if ( $graph->self_loop_vertices );
>=20
> if (! $doall ) {
>=20
> #
> # If not looking at all pkgs/ports, trim the tree
> #
>=20
>     my $tcgraph =3D $graph->TransitiveClosure_Floyd_Warshall;
>=20
> #
> # Mark and sweep
> #
>=20
> #
> # Note that the output of pkg_version is "unqualified"=20
> # create a new list that identifies all old and new targets
> #
>=20
>     my %tgt_pkgs;
>     my $tgtmatch;
>=20
>     foreach $pkg ($graph->vertices) {
> 	$graph->delete_attribute('candidate', $pkg);
> 	foreach $target (keys %targets) {
> 	    $tgtmatch =3D "^" . quotemeta($target);
> 	    $tgt_pkgs{$pkg} =3D 'true' if $pkg =3D~/$tgtmatch/;
> 	}
>     }
>=20
>     foreach $target (keys %tgt_pkgs) {
> #	print "setting $target\n";
> 	$graph->set_attribute('candidate', $target, 'true') ;
> 	foreach $pkg ($graph->vertices) {
> 	    $graph->set_attribute('candidate', $pkg, 'true')=20
> #		&&  print "setting $pkg as dependent on $target\n"
> 		    if $tcgraph->has_edge($target, $pkg);
> 	}
>     }
>    =20
>     foreach $pkg ($graph->vertices) {
> 	$graph->delete_vertex($pkg)=20
> 	    unless $graph->get_attribute('candidate', $pkg);
>     }
>    =20
> }
>=20
> #
> # Start dumping out the order of processing
> #
>=20
> my $level =3D 0;
> my @pkgs;
>=20
> while ( $graph->vertices ) {
>=20
>     print "\n\nLevel ${level}:\n";
>     print "=3D=3D=3D=3D=3D=3D=3D=3D\n";
>     @pkgs =3D ($graph->isolated_vertices, $graph->source_vertices);
>=20
>     print join("\n", sort(@pkgs));
>=20
>     $graph->delete_vertices(@pkgs);
>=20
>     die "No packages found which can be built at this level, unable to re=
solve"
> 	unless @pkgs;
>=20
>     $level++;
> }
>=20
> print "\n\nDone\n";
>=20
> exit EXIT_SUCCESS;
>=20
>=20
> To Unsubscribe: send mail to majordomo@FreeBSD.org
> with "unsubscribe freebsd-stable" in the body of the message

--C7zPtVaVf+AK4Oqc
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.4 (FreeBSD)
Comment: For info see http://www.gnupg.org

iD8DBQE65hoZKxA01iDoLN4RAtUTAKC6k83cgEQ9Q3k1iTCg1rqJLNN8gQCfbFPN
aE7KiKwFYpYFyxa2f56gjzU=
=GlXM
-----END PGP SIGNATURE-----

--C7zPtVaVf+AK4Oqc--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message




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