3 # debi: Install current version of deb package
4 # debc: List contents of current version of deb package
6 # debi and debc originally by Christoph Lameter <clameter@debian.org>
7 # Copyright Christoph Lameter <clameter@debian.org>
8 # The now defunct debit originally by Jim Van Zandt <jrv@vanzandt.mv.com>
9 # Copyright 1999 Jim Van Zandt <jrv@vanzandt.mv.com>
10 # Modifications by Julian Gilbey <jdg@debian.org>, 1999-2003
11 # Copyright 1999-2003, Julian Gilbey <jdg@debian.org>
13 # This program is free software; you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation; either version 2 of the License, or
16 # (at your option) any later version.
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
30 use filetest 'access';
33 use Dpkg::Changelog::Parse;
35 my $progname = basename($0,'.pl'); # the '.pl' is for when we're debugging
36 my $modified_conf_msg;
40 Usage: $progname [options] [.changes file] [package ...]
41 Install the .deb file(s) just created, as listed in the generated
42 .changes file or the .changes file specified. If packages are listed,
43 only install those specified packages from the .changes file.
45 --no-conf or Don\'t read devscripts config files;
46 --noconf must be the first option given
47 -a<arch> Search for .changes file made for Debian build <arch>
48 -t<target> Search for .changes file made for GNU <target> arch
49 --debs-dir DIR Look for the changes and debs files in DIR instead of
50 the parent of the current package directory
51 --multi Search for multiarch .changes file made by dpkg-cross
52 --upgrade Only upgrade packages; don't install new ones.
53 --check-dirname-level N
54 How much to check directory names:
56 N=1 only if program changes directory (default)
58 --check-dirname-regex REGEX
59 What constitutes a matching directory name; REGEX is
60 a Perl regular expression; the string \`PACKAGE\' will
61 be replaced by the package name; see manpage for details
62 (default: 'PACKAGE(-.+)?')
63 --with-depends Install packages with their depends.
64 --tool TOOL Use the specified tool for installing the dependencies
65 of the package(s) to be installed.
67 --help Show this message
68 --version Show version and copyright information
70 Default settings modified by devscripts configuration files:
77 Usage: $progname [options] [.changes file] [package ...]
78 Display the contents of the .deb or .udeb file(s) just created, as listed
79 in the generated .changes file or the .changes file specified.
80 If packages are listed, only display those specified packages
81 from the .changes file. Options:
82 --no-conf or Don\'t read devscripts config files;
83 --noconf must be the first option given
84 -a<arch> Search for changes file made for Debian build <arch>
85 -t<target> Search for changes file made for GNU <target> arch
86 --debs-dir DIR Look for the changes and debs files in DIR instead of
87 the parent of the current package directory
88 --multi Search for multiarch .changes file made by dpkg-cross
89 --check-dirname-level N
90 How much to check directory names:
92 N=1 only if program changes directory (default)
94 --check-dirname-regex REGEX
95 What constitutes a matching directory name; REGEX is
96 a Perl regular expression; the string \`PACKAGE\' will
97 be replaced by the package name; see manpage for details
98 (default: 'PACKAGE(-.+)?')
99 --help Show this message
100 --version Show version and copyright information
102 Default settings modified by devscripts configuration files:
107 if ($progname eq 'debi') { *usage = \&usage_i; }
108 elsif ($progname eq 'debc') { *usage = \&usage_c; }
109 else { die "Unrecognised invocation name: $progname\n"; }
111 my $version = <<"EOF";
112 This is $progname, from the Debian devscripts package, version ###VERSION###
113 This code is copyright 1999-2003, Julian Gilbey <jdg\@debian.org>,
115 Based on original code by Christoph Lameter and James R. Van Zandt.
116 This program comes with ABSOLUTELY NO WARRANTY.
117 You are free to redistribute this code under the terms of
118 the GNU General Public License, version 2 or later.
121 # Start by setting default values
124 my $check_dirname_level = 1;
125 my $check_dirname_regex = 'PACKAGE(-.+)?';
126 my $install_tool = 'apt-get';
128 # Next, read configuration files and then command line
129 # The next stuff is boilerplate
131 if (@ARGV and $ARGV[0] =~ /^--no-?conf$/) {
132 $modified_conf_msg = " (no configuration files read)";
135 my @config_files = ('/etc/devscripts.conf', '~/.devscripts');
137 'DEBRELEASE_DEBS_DIR' => '..',
138 'DEVSCRIPTS_CHECK_DIRNAME_LEVEL' => 1,
139 'DEVSCRIPTS_CHECK_DIRNAME_REGEX' => 'PACKAGE(-.+)?',
141 my %config_default = %config_vars;
145 foreach my $var (keys %config_vars) {
146 $shell_cmd .= qq[$var="$config_vars{$var}";\n];
148 $shell_cmd .= 'for file in ' . join(" ",@config_files) . "; do\n";
149 $shell_cmd .= '[ -f $file ] && . $file; done;' . "\n";
151 foreach my $var (keys %config_vars) { $shell_cmd .= "echo \$$var;\n" }
152 my $shell_out = `/bin/bash -c '$shell_cmd'`;
153 @config_vars{keys %config_vars} = split /\n/, $shell_out, -1;
156 $config_vars{'DEVSCRIPTS_CHECK_DIRNAME_LEVEL'} =~ /^[012]$/
157 or $config_vars{'DEVSCRIPTS_CHECK_DIRNAME_LEVEL'}=1;
158 # We do not replace this with a default directory to avoid accidentally
159 # installing a broken package
160 $config_vars{'DEBRELEASE_DEBS_DIR'} =~ s%/+%/%;
161 $config_vars{'DEBRELEASE_DEBS_DIR'} =~ s%(.)/$%$1%;
162 if (! -d $config_vars{'DEBRELEASE_DEBS_DIR'}) {
163 $debsdir_warning = "config file specified DEBRELEASE_DEBS_DIR directory $config_vars{'DEBRELEASE_DEBS_DIR'} does not exist!";
166 foreach my $var (sort keys %config_vars) {
167 if ($config_vars{$var} ne $config_default{$var}) {
168 $modified_conf_msg .= " $var=$config_vars{$var}\n";
171 $modified_conf_msg ||= " (none)\n";
172 chomp $modified_conf_msg;
174 $debsdir = $config_vars{'DEBRELEASE_DEBS_DIR'};
175 $check_dirname_level = $config_vars{'DEVSCRIPTS_CHECK_DIRNAME_LEVEL'};
176 $check_dirname_regex = $config_vars{'DEVSCRIPTS_CHECK_DIRNAME_REGEX'};
179 # Command line options next
180 my ($opt_help, $opt_version, $opt_a, $opt_t, $opt_debsdir, $opt_multi);
182 my ($opt_level, $opt_regex, $opt_noconf);
183 my ($opt_tool, $opt_with_depends);
184 GetOptions("help" => \$opt_help,
185 "version" => \$opt_version,
188 "debs-dir=s" => \$opt_debsdir,
189 "multi" => \$opt_multi,
190 "upgrade" => \$opt_upgrade,
191 "check-dirname-level=s" => \$opt_level,
192 "check-dirname-regex=s" => \$opt_regex,
193 "with-depends" => \$opt_with_depends,
194 "tool=s" => \$opt_tool,
195 "noconf" => \$opt_noconf,
196 "no-conf" => \$opt_noconf,
198 or die "Usage: $progname [options] [.changes file] [package ...]\nRun $progname --help for more details\n";
200 if ($opt_help) { usage(); exit 0; }
201 if ($opt_version) { print $version; exit 0; }
203 die "$progname: --no-conf is only acceptable as the first command-line option!\n";
206 my ($targetarch, $targetgnusystem);
207 $targetarch = $opt_a ? "-a$opt_a" : "";
208 $targetgnusystem = $opt_t ? "-t$opt_t" : "";
211 $opt_debsdir =~ s%/+%/%;
212 $opt_debsdir =~ s%(.)/$%$1%;
213 if (! -d $opt_debsdir) {
214 $debsdir_warning = "--debs-dir directory $opt_debsdir does not exist!";
216 $debsdir = $opt_debsdir;
219 if ($debsdir_warning) {
220 die "$progname: $debsdir_warning\n";
223 if (defined $opt_level) {
224 if ($opt_level =~ /^[012]$/) { $check_dirname_level = $opt_level; }
226 die "$progname: unrecognised --check-dirname-level value (allowed are 0,1,2)\n";
230 if (defined $opt_regex) { $check_dirname_regex = $opt_regex; }
233 $install_tool = $opt_tool;
236 # Is a .changes file listed on the command line?
237 my ($changes, $mchanges, $arch);
238 if (@ARGV and $ARGV[0] =~ /\.changes$/) {
242 # Need to determine $arch in any event
243 $arch = `dpkg-architecture $targetarch $targetgnusystem -qDEB_HOST_ARCH`;
244 if ($? != 0 or ! $arch) {
245 die "$progname: unable to determine target architecture.\n";
251 if (! defined $changes) {
252 # Look for .changes file via debian/changelog
253 until (-r 'debian/changelog') {
255 chdir '..' or die "$progname: can't chdir ..: $!\n";
257 die "$progname: cannot find readable debian/changelog anywhere!\nAre you in the source code tree?\n";
261 if (-e ".svn/deb-layout") {
262 # Cope with format of svn-buildpackage tree
264 open($fh, "<", ".svn/deb-layout") || die "Can't open .svn/deb-layout: $!\n";
265 my($build_area) = grep /^buildArea=/, <$fh>;
267 if (defined($build_area) and not $opt_debsdir) {
269 $build_area =~ s/^buildArea=//;
270 $debsdir = $build_area if -d $build_area;
274 # Find the source package name and version number
275 my $changelog = changelog_parse();
277 die "$progname: no package name in changelog!\n"
278 unless exists $changelog->{'Source'};
279 die "$progname: no package version in changelog!\n"
280 unless exists $changelog->{'Version'};
282 # Is the directory name acceptable?
283 if ($check_dirname_level == 2 or
284 ($check_dirname_level == 1 and $chdir)) {
285 my $re = $check_dirname_regex;
286 $re =~ s/PACKAGE/\\Q$changelog->{'Source'}\\E/g;
288 if ($re =~ m%/%) { $gooddir = eval "cwd() =~ /^$re\$/;"; }
289 else { $gooddir = eval "basename(cwd()) =~ /^$re\$/;"; }
294 $progname: found debian/changelog for package $changelog->{'Source'} in the directory
296 but this directory name does not match the package name according to the
297 regex $check_dirname_regex.
299 To run $progname on this package, see the --check-dirname-level and
300 --check-dirname-regex options; run $progname --help for more info.
305 my $sversion = $changelog->{'Version'};
306 $sversion =~ s/^\d+://;
307 my $package = $changelog->{'Source'};
308 my $pva="${package}_${sversion}_${arch}";
309 $changes="$debsdir/$pva.changes";
311 if (! -e $changes and -d ".svn" and -d "../build-area") {
312 # Try out default svn-buildpackage structure in case
313 # we were going to fail anyway...
314 $changes = "../build-area/$pva.changes";
318 my @mchanges = glob("$debsdir/${package}_${sversion}_*+*.changes");
319 @mchanges = grep { /[_+]$arch[\.+]/ } @mchanges;
320 $mchanges = $mchanges[0] || '';
321 $mchanges ||= "$debsdir/${package}_${sversion}_multi.changes"
322 if -f "$debsdir/${package}_${sversion}_multi.changes";
326 chdir dirname($changes)
327 or die "$progname: can't chdir to $changes directory: $!\n";
328 $changes = basename($changes);
329 $mchanges = basename($mchanges) if $opt_multi;
331 if (! -r $changes or $opt_multi and $mchanges and ! -r $mchanges) {
332 die "$progname: can't read $changes" .
333 (($opt_multi and $mchanges) ? " or $mchanges" : "") . "!\n";
336 if (! -r $changes and $opt_multi) {
337 $changes = $mchanges;
341 # $opt_multi now tells us whether we're actually using a multi-arch .changes
345 my %pkgs = map { $_ => 0 } @ARGV;
346 my $ctrl = Dpkg::Control->new(name => $changes, type => CTRL_FILE_CHANGES);
347 $ctrl->load($changes);
348 for (split(/\n/, $ctrl->{Files})) {
349 # udebs are only supported for debc
350 if ((($progname eq 'debi') && (/ (\S*\.deb)$/)) ||
351 (($progname eq 'debc') && (/ (\S*\.u?deb)$/))) {
353 $deb =~ /^([a-z0-9+\.-]+)_/ or warn "unrecognised .deb name: $deb\n";
354 # don't want other archs' .debs:
355 next unless $deb =~ /[_+]($arch|all)[\.+]/;
360 if (exists $pkgs{$pkg}) {
363 } elsif (exists $pkgs{$deb}) {
374 die "$progname: no appropriate .debs found in the changes file $changes!\n";
377 if ($progname eq 'debi') {
378 my @upgrade = $opt_upgrade ? ('-O') : ();
379 if ($opt_with_depends) {
380 system('debpkg', @upgrade, '--unpack', @debs) == 0
381 or die "$progname: debpkg --unpack failed \n";
382 system($install_tool, '-f', 'install') == 0
383 or die "$progname: " . $install_tool . ' -f install failed\n';
385 system('debpkg', @upgrade, '-i', @debs) == 0
386 or die "$progname: debpkg -i failed\n";
389 # $progname eq 'debc'
390 foreach my $deb (@debs) {
392 print '-' x length($deb), "\n";
393 system('dpkg-deb', '-I', $deb) == 0
394 or die "$progname: dpkg-deb -I $deb failed\n";
395 system('dpkg-deb', '-c', $deb) == 0
396 or die "$progname: dpkg-deb -c $deb failed\n";
401 # Now do a sanity check
403 foreach my $pkg (keys %pkgs) {
404 if ($pkgs{$pkg} == 0) {
405 warn "$progname: package $pkg not found in $changes, ignoring\n";
406 } elsif ($pkgs{$pkg} > 1) {
407 warn "$progname: package $pkg found more than once in $changes, installing all\n";