#!/usr/bin/perl # Usage: all-packages # Run this script from a build area after running gen-packages and # dasource. The script will output a list of normal Debian packages # (not equivs or debathenify packages) in dependency order. # # This script is imperfect in a couple of ways: # # (1) It knows nothing about Provides declarations, because those are # computed when a package is built and this script is intended to # operate before binary packages are built. # # (2) It will always pick the first package of a disjunction. use strict; # Process a Build-Depends specification into a list of package names. sub list { my ($l) = @_; my @a = split(/, /, $l); foreach (@a) { s/ \(.*\)$//; s/ \|.*$//; s/ \[.*$//; } return @a; } # Read in the package-to-directory map. my %dirmap; open(PACKAGES, "<", "packages") || die "Can't read packages file; create with gen-packages"; while () { chomp; /^(\S+)\s+(\S+)$/ || die "Malformed packages line"; $dirmap{$1} = $2; } close(PACKAGES); # Read the dsc file for each package to get build dependencies. my %deps; foreach my $name (keys(%dirmap)) { # Look for dsc files under $name and pick the one that sorts highest. my @dscfiles = sort glob("$name/*.dsc"); if (scalar @dscfiles == 0) { die "No source package for $name; create with dasource" } my $dscfile = $dscfiles[$#dscfiles]; open(DSC, "<", $dscfile) || die "Can't read $dscfile"; $deps{$name} = []; while () { chomp; (my ($depline) = /^Build-Depends: (.*)$/) || next; push @{$deps{$name}}, list($depline); } close(DSC); } # Recursively output a package's dependency names and then the package # name itself, without outputting any name twice. my %done; sub process { my ($name) = @_; return if ($done{$name}); foreach my $dep (@{${deps{$name}}}) { process($dep) if ($dirmap{$dep}); } print $name, "\n"; $done{$name} = 1; } foreach my $name (keys(%dirmap)) { process($name); }