source: trunk/debathena/debathena/thirdparty/generate-package-list.pl @ 25843

Revision 25843, 3.4 KB checked in by jdreed, 11 years ago (diff)
New implementation of thirdparty (Trac: #1156) Allow removal of thirdparty packages in chroot (Trac: #372)
  • Property svn:executable set to *
Line 
1#!/usr/bin/perl
2
3$| = 1;
4use warnings;
5use strict;
6use locale; # for sort
7use Cwd qw(abs_path);
8use File::Basename;
9
10use Getopt::Std;
11use AptPkg::Config '$_config';
12use AptPkg::Cache;
13
14my $path = dirname(abs_path($0));
15our ($opt_n, $opt_l, $opt_d) = (0,
16                                $path . "/lists",
17                                $path);
18
19getopts('nl:d:');
20
21sub debug {
22    if ($opt_n) {
23        print join(' ', 'D:', @_, "\n");
24    }
25}
26
27my $codename = `lsb_release -sc`;
28die "Can't determine codename" unless ($? == 0);
29chomp($codename);
30
31(-d $opt_l) || die "$opt_l is not a directory";
32(-d $opt_d) || die "$opt_d is not a directory";
33
34print "Using lists in $opt_l\nWriting output files to $opt_d\n";
35
36debug("Initializing APT cache");
37# Initialize the APT configuration
38$_config->init;
39my $cache = AptPkg::Cache->new;
40my $policy = $cache->policy;
41
42my %packages = ();
43my %depends = ();
44
45open(COMMON, join('/', $opt_l, 'common')) || die "Can't open $opt_l/common";
46debug("Reading 'common' file...");
47while (<COMMON>) {
48    chomp;
49    s/^\s+//;
50    s/\s+$//;
51    next if /^#/;
52    next unless /\S/;
53    if (/^-/) {
54        warn "Ignoring invalid package exclusion in the common file, line $.";
55        next;
56    }
57    if (/^(\S+) \| (\S+)$/) {
58        debug("Examining conditional line: $_");
59        foreach my $p ($1, $2) {
60            debug("Checking for $p");
61            if ($cache->{$p} && $cache->{$p}->{VersionList}) {
62                debug("Adding $p to dependencies");
63                $packages{$p} = 1;
64                last;
65            }
66        }
67        unless (exists($packages{$1}) || exists($packages{$2})) {
68            warn "Could not satisfy conditional dependency: $_!";
69        }
70    } elsif (/^(\S+)(?: (\S+))+$/) {
71        my ($pkg1, @rest) = (split(' ', $_));
72        $packages{$pkg1} = 1;
73        $depends{$pkg1} = \@rest;
74    } elsif (/^\?(\S+)$/) {
75        debug("Adding $1 to recommendations");
76        $packages{$1} = 2;
77    } else {
78        debug("Adding $_ to dependencies");
79        $packages{$_} = 1;
80    }
81}
82close(COMMON);
83
84open(DIST, join('/', $opt_l, $codename)) || die "Can't open $opt_l/$codename";
85debug("Reading distro-specific file");
86while (<DIST>) {
87    chomp;
88    s/^\s+//;
89    s/\s+$//;
90    next if /^#/;
91    next unless /\S/;
92    if (/^-(\S+)$/) {
93        if (exists($packages{$1})) {
94            debug("Deleting $1 from package list.");
95            delete($packages{$1});
96        } else {
97            warn("Package $1 is not in package list, so can't remove it.");
98        }
99    } elsif (/^\?(\S+)$/) {
100        debug("Adding $1 to recommendations");
101        $packages{$1} = 2;
102    } else {
103        debug("Adding $_ to dependencies");
104        $packages{$_} = 1;
105    }
106}
107close(DIST);
108
109foreach my $pkgname (sort(keys(%packages))) {
110    my $pkg = $cache->{$pkgname};
111    if (! $pkg) {
112        debug("Removing $pkgname as it can't be found in the APT cache.");
113        delete($packages{$pkgname});
114        if (exists($depends{$pkgname})) {
115            foreach (@{$depends{$pkgname}}) {
116                debug("Removing $_ because we removed $pkgname");
117                delete($packages{$_});
118            }
119        }
120        next;
121    }
122    if (! $pkg->{VersionList}) {
123        debug("Removing $pkgname as it has no version candidate");
124        delete($packages{$pkgname});
125        if (exists($depends{$pkgname})) {
126            foreach (@{$depends{$pkgname}}) {
127                debug("Removing $_ because we removed $pkgname");
128                delete($packages{$_});
129            }
130        }
131        next;
132    }
133}
134
135debug("Writing out lists");
136open(DEPS, '>', join('/', $opt_d, 'dependencies')) || die "Can't open $opt_d/dependencies for writing";
137open(RECS, '>', join('/', $opt_d, 'recommendations')) || die "Can't open $opt_d/dependencies for writing";
138foreach (sort(keys(%packages))) {
139    if ($packages{$_} == 2) {
140        print RECS "$_\n";
141    } else {
142        print DEPS "$_\n";
143    }
144}
145close(DEPS);
146close(RECS);
147print "Done.\n";
148exit 0;
149       
Note: See TracBrowser for help on using the repository browser.