Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 Apr 2001 08:35:16 -0700 (PDT)
From:      Jeff Kletsky <Jeff+freebsd@wagsky.com>
To:        freebsd-stable@freebsd.org
Cc:        bmah@freebsd.org
Subject:   pkg/port dependency tool (enclosed)
Message-ID:  <Pine.BSF.4.21.0104230806060.27435-100000@wildside.wagsky.com>

next in thread | raw e-mail | index | archive | help
I saw that in the release notes for 4.3 that the pkg_* toolset was being
enhanced to track where a given pkg/port comes from.  I have been
wrestling with the upgrade process for a while, especially when it comes
to dependencies, and am offering back to the project a Perl script that
provides output that can be run through dot(1) (available in the port
graphics/graphviz) to produce a dependency graph. 

Looking at this graph makes it clear to a human which port to upgrade
first based on its dependencies. You can reverse the dependencies to see
which one will pull in the most as dependencies as well.

I'm thinking through the automation of this right now. There are issues
with loops in the dependency graph which need to be detected and
resolved. Detection should not be an issue, resolution is
tougher. The "build twice" approach *may* be sufficient, but that horrid
possibility of each node exposing functionality that is dependent on a
predecessor worries me a (tiny) bit. Let's hope that most of the software
is well designed...

I would be happy to contribute to the enhancement of the pkg/port tools
in a more targeted way if the appropriate lead would let me know.

Jeff

P.S. This type of dependency checking might also allow the "make
clean" process a bit smarter and faster (the other option there would be
to specify a flag that says not to follow dependencies on a recursive
"clean", especially in /usr/ports)


In any event, here is the Perl code:
====================================

#!/usr/bin/perl -w

# $Header: /usr/local/cvsroot/pkg_graph/get_depends.pl,v 1.3 2001/04/22 18:50:19 jeff Exp $

# Tool to read from /var/db/pkg to find all pkg/port dependencies
# and eventually write out a file for dot(1)


use strict;
use POSIX qw(EXIT_FAILURE EXIT_SUCCESS);
use FileHandle;

my $usage = qq(
Usage:
$0 [-r]

Prints output for dot(1) based on installed package/port dependencies

  -r   Reverses the direction of the dependencies in the graph

);

my $reverse = 0;

if ( $#ARGV > 0 ) {
    die $usage;
}

if ( $#ARGV == 0 ) {
    $reverse = ( shift @ARGV eq "-r" );
    die $usage unless $reverse;
}

my $pkg_db_dir = '/var/db/pkg';
$pkg_db_dir =~ s/\/$//;             # prevent "trailing-slash" issue

my $required_by_filename = '+REQUIRED_BY';


#
# Open the directory that contains pkg/port information
#

opendir (VARDBPKG, $pkg_db_dir) or die "Unable to open $pkg_db_dir: $!";

#
# Get the subdirectories, and iterate through them
#

my @allfiles = readdir VARDBPKG;

die "No files read in $pkg_db_dir\n" unless $#allfiles > 1;

my $pkg;
my $rqd;
my $required_by_fqn;
my $required_by_fh;

#
# dot(1) doesn't like standard package names, 
# seeming to split then at the -
#

my %nodes;
my $node = 0;

my $pkg_node;
my $rqd_node;

#
# Write the dot(1) header
#

print 'digraph G {';
print "\n";
print qq(rankdir=LR;
color=white;
/* size="8.5,11"; */
node [color=lightgray,style=filled];
);


#
# Now deal with the rest
#

 PKG:

    foreach $pkg (sort @allfiles) {
	
	
	next PKG if $pkg =~ m/^\./;

	print qq(\t"${pkg}";\n);  # Add the node

	
#
# See if there is a +REQUIRED_BY file, open it, and process lines
#
	
	$required_by_fqn = "${pkg_db_dir}/${pkg}/${required_by_filename}";

	next PKG unless -e $required_by_fqn;
	
	$required_by_fh = new FileHandle "< $required_by_fqn";
	die "Unable to open $required_by_fqn: $!" 
	    unless defined $required_by_fh;
	
	while ($rqd = <$required_by_fh>) {

	    chomp $rqd;
	    
	    if ( $reverse ) {
		print qq(\t\t"${rqd}" -> "${pkg}";\n);
	    } else {
		print qq(\t\t"${pkg}" -> "${rqd}";\n);
	    }		
	}

    } # PKG
    

#
# Close the dot(1) output
#

print '}';
print "\n";
exit EXIT_SUCCESS;



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?Pine.BSF.4.21.0104230806060.27435-100000>