[Pkg-ocaml-maint-commits] r1046 - tools/build-dep-graph

Stefano Zacchiroli zack@costa.debian.org
Wed, 23 Mar 2005 11:56:21 +0100


Author: zack
Date: 2005-03-23 11:56:21 +0100 (Wed, 23 Mar 2005)
New Revision: 1046

Modified:
   tools/build-dep-graph/build-dep-graph.pl
Log:
- bugfix: enforced the invariant that graph nodes are labeled with source
  package names, even if they are providing a virtual dependency (e.g. no more
  ocaml-nox node)
- bugfix: consider both Build-Depends and Build-Depends-Indep
- added debugging messages which could be turned on setting $debug = 1
- supports reading package list from STDIN
- changed copyright to my debian address
- added documentation in the script comment



Modified: tools/build-dep-graph/build-dep-graph.pl
===================================================================
--- tools/build-dep-graph/build-dep-graph.pl	2005-03-23 08:04:27 UTC (rev 1045)
+++ tools/build-dep-graph/build-dep-graph.pl	2005-03-23 10:56:21 UTC (rev 1046)
@@ -1,19 +1,37 @@
 #!/usr/bin/perl -w
 #
-# Copyright (C) 2005, Stefano Zacchiroli <zack@cs.unibo.it>
+# Copyright (C) 2005, Stefano Zacchiroli <zack@debian.org>
 #
 # This is free software, you can redistribute it and/or modify it under the
 # terms of the GNU General Public License version 2 as published by the Free
 # Software Foundation.
 #
+# Build the build dependency graph of a set of packages.
+#
 # Usage: build-dep-graph.pl pkgname ...
 #
+# Given as input a list of package names (both source package and binary package
+# names are ok) create a graphviz graph of build dependencies among them. Graph
+# nodes are labelled with source packages name and graph edges A -> B indicates
+# that source package A build depend on source package B. Virtual packages are
+# handled, if more than one packages provide a given build dependency the first
+# one is chosed. Only packages specified by the user are considered in the
+# graph, this means that you can't invoke it on a single package name to have a
+# graph of all its build dependencies. If no package name is specified on
+# command line, the list of packages is read from standard input.
+#
+# The intended usage of this script is to discover the proper upload order of a
+# set of packages so that the build daemon wont fail for a missing build
+# dependency.
+#
 
 use strict;
 use AptPkg::Cache;
 use AptPkg::Source;
 
-die "No package specified\n" if ($#ARGV == -1);
+my $debug = 0;
+
+@ARGV = <> if ($#ARGV == -1);
 my $aptSrc = AptPkg::Source->new();
 my $aptCache = AptPkg::Cache->new();
 
@@ -22,12 +40,13 @@
 sub provides($) {
   my $name = shift;
   my $info = $aptCache->{$name} || die "Can't get cache info for $name\n";
-  my @pkgs = ();
+  my @pkgs;
   if (exists $info->{"ProvidesList"}) {
     foreach my $p (@{$info->{"ProvidesList"}}) {
       push @pkgs, $p->{"OwnerPkg"}{"Name"};
     }
-    return (shift @pkgs);
+    my $fstProvide = shift @pkgs;
+    return $fstProvide
   } else {
     return 0;
   }
@@ -36,16 +55,24 @@
 # binary (or source) package name -> source package name resolution
 sub resolve($) {
   my $name = shift;
-  my $srcname = $aptSrc->find($name) || provides($name);
+  print STDERR "resolve($name) = " if $debug;
+  my $srcname = $aptSrc->find($name);
+  if (not $srcname) { # resolution failed, check if someone provides it
+    $srcname = provides($name);
+      # if someone provides it, we still need to resolve bin->src
+    $srcname = $aptSrc->find($srcname) if $srcname;
+  }
+  print STDERR "$srcname\n" if $debug;
   return $srcname;
 }
 
-# resolve all provided name to source package names
-my @srcPkgs = ();
+# resolve all provided names to source package names
+my %resolved;
 foreach my $p (@ARGV) {
-  my $resolved = resolve($p) || $p;
-  push @srcPkgs, $resolved;
+  my $src_name = resolve($p) || die "Can't find source name for $p\n";
+  $resolved{$src_name} = 1; # dummy value
 }
+my @srcPkgs = keys %resolved;
 
 # return true if a given package has to be considered in the dependency graph,
 # false otherwise (i.e. it is part of packages specified on command line)
@@ -72,6 +99,7 @@
 # add a dependency between two packages, given their name
 sub add_dep($$) {
   my ($src_pkg, $dst_pkg) = (@_);
+  print STDERR "add_dep($src_pkg,$dst_pkg)\n" if $debug;
   my $src_node = $nodes{$src_pkg} || new_node($src_pkg);
   my $dst_node = $nodes{$dst_pkg} || new_node($dst_pkg);
   push @deps, "$src_node -> $dst_node;";
@@ -102,9 +130,14 @@
     print STDERR "Processing $pkg ...\n";
     $processed{$pkg} = 1;
     my $info = $aptSrc->get($pkg);
-    my $buildDeps = $$info[0]{"BuildDepends"}{"Build-Depends"};
-    foreach my $d (@$buildDeps) {
+    my $buildDeps1 = $$info[0]{"BuildDepends"}{"Build-Depends"};
+    my $buildDeps2 = $$info[0]{"BuildDepends"}{"Build-Depends-Indep"};
+    my @buildDeps;
+    push @buildDeps, @$buildDeps1 if $buildDeps1;
+    push @buildDeps, @$buildDeps2 if $buildDeps2;
+    foreach my $d (@buildDeps) {
       my $dep = $$d[0];
+      print STDERR "found dependency $dep\n" if $debug;
       $dep = resolve($dep);
       next unless $dep;
       if (consider($dep)) {