3
# origtargz: fetch the orig tarball of a Debian package from various sources,
5
# Copyright (C) 2012 Christoph Berg <myon@debian.org>
7
# This program is free software: you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation, either version 2 of the License, or
10
# (at your option) any later version.
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
17
# You should have received a copy of the GNU General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
22
origtargz - fetch the orig tarball of a Debian package from various sources, and unpack it
28
=item B<origtargz> [I<OPTIONS>] [B<--unpack>[=B<no>|B<once>|B<yes>]]
30
=item B<origtargz> B<--help>
36
B<origtargz> downloads the orig tarball of a Debian package, and optionally
37
unpacks it into the current directory. The version number to be used is
38
determined from F<debian/changelog>. The main use for B<origtargz> is with
39
debian-dir-only repository checkouts. It should be invoked from the top level
40
directory of an unpacked Debian source package.
42
Various download locations are tried:
46
=item * First, an existing file is looked for.
48
=item * Directories given with B<--path> are searched.
50
=item * B<apt-get source> is tried when B<apt-cache showsrc> reports a matching version.
52
=item * Finally, B<uscan --download-current-version> is tried.
56
When asked to unpack the orig tarball, B<origtargz> will remove all files and
57
directories from the current directory, except the debian directory, and the
58
VCS repository directories. Some files outside F<debian/> which are often stored
59
in VCS even for debian-dir-only repositories are also preserved (F<.bzr-builddeb>,
60
F<.gitignore>, F<.hgignore>). I<Note that this will drop all non-committed changes>
61
for the patch system in use (e.g. source format "3.0 (quilt)"), and will even
62
remove all patches from the package when no patch system is in use (the
63
original "1.0" source format).
65
The default behavior is to unpack the orig tarball on the first invocation of
66
B<origtargz> in a debian-dir-only checkout.
70
Despite B<origtargz> being called "targz", it will work with any compression
71
scheme used for the tarball.
73
A similar tool to unpack orig tarballs is B<uupdate>(1). B<uupdate> creates a
74
new working directory, unpacks the tarball, and applies the Debian F<.diff.gz>
75
changes. In contrast, B<origtargz> uses the current directory, keeping VCS
78
For Debian package repositories that keep the full upstream source, other tools
79
should be used to upgrade the repository from the new tarball. See
80
B<git-import-orig>(1) and B<svn-upgrade>(1) for examples. B<origtargz> is still
81
useful for downloading the current tarball.
87
=item B<-p>, B<--path> I<directory>
89
Add I<directory> to the list of locations to search for an existing tarball.
90
When found, a hardlink is created if possible, otherwise a symlink.
92
=item B<-u>, B<--unpack>[=B<no>|B<once>|B<yes>]
94
Unpack the downloaded orig tarball to the current directory, replacing
95
everything except the debian directory. Existing files are removed, except for
96
F<debian/> and VCS files. Preserved are: F<.bzr>, F<.bzrignore>,
97
F<.bzr-builddeb>, F<.git>, F<.gitignore>, F<.hg>, F<.hgignore>, and F<.svn>.
103
Do not unpack the orig tarball.
105
=item B<once> (default when B<--unpack> is not used)
107
If the current directory contains only a F<debian> directory (and possibly some
108
dotfiles), unpack the orig tarball. This is the default behavior.
110
=item B<yes> (default for B<--unpack> without argument)
112
Always unpack the orig tarball.
116
=item B<-d>, B<--download-only>
118
Alias for B<--unpack=no>.
120
=item B<-t>, B<--tar-only>
122
When using B<apt-get source>, pass B<--tar-only> to it. The default is to
123
download the full source package including F<.dsc> and F<.diff.gz> or
124
F<.debian.tar.gz> components so B<debdiff> can be used to diff the last upload
125
to the next one. With B<--tar-only>, only download the F<.orig.tar.*> file.
129
Remove existing files as with B<--unpack>. Note that like B<--unpack>, this
130
will remove upstream files even if they are stored in VCS.
136
#=head1 CONFIGURATION VARIABLES
138
#The two configuration files F</etc/devscripts.conf> and
139
#F<~/.devscripts> are sourced by a shell in that order to set
140
#configuration variables. Command line options can be used to override
141
#configuration file settings. Environment variable settings are ignored
142
#for this purpose. The currently recognised variables are:
146
B<debcheckout>(1), B<git-import-orig>(1), B<svn-upgrade>(1), B<uupdate>(1)
150
B<origtargz> and this manpage have been written by Christoph Berg
151
<I<myon@debian.org>>.
159
use File::Temp qw/tempdir/;
160
use Getopt::Long qw(:config gnu_getopt);
165
my $unpack = 'once'; # default when --unpack is not used
169
"path|p=s" => \@dirs,
170
"download-only|d" => sub { $unpack = 'no' },
171
"help|h" => sub { pod2usage({-exitval => 0, -verbose => 1}); },
172
"tar-only|t" => \$tar_only,
173
"unpack|u:s" => \$unpack,
175
) or pod2usage({-exitval => 3});
177
$unpack = 'yes' if (defined $unpack and $unpack eq ''); # default for --unpack without argument
178
pod2usage({-exitval => 3}) if (@ARGV > 0 or $unpack !~ /^(no|once|yes)$/);
180
# get package name and version number
182
my ($package, $version, $origversion, $fileversion);
184
open F, "debian/changelog" or die "debian/changelog: $!\n";
187
unless ($line =~ /^(\S+) \((\S+)\)/) {
188
die "could not parse debian/changelog:1: $line";
190
($package, $version) = ($1, $2);
191
unless ($version =~ /-/) {
192
print "Package with native version number $version, skipping orig.tar.* download\n";
195
$origversion = $version;
196
$origversion =~ s/(.*)-.*/$1/; # strip everything from the last dash
197
$fileversion = $origversion;
198
$fileversion =~ s/^\d+://; # strip epoch
202
sub download_origtar ()
204
# look for an existing file
206
if (my @f = glob "../${package}_$fileversion.orig.tar.*") {
207
print "Using existing $f[0]\n";
211
# try other directories
213
foreach my $dir (@dirs) {
216
if (my @f = glob "$dir/${package}_$fileversion.orig.tar.*") {
217
print "Using $f[0]\n";
218
my $basename = $f[0];
219
$basename =~ s!.*/!!;
220
link $f[0], "../$basename" or
221
symlink $f[0], "../$basename" or
229
my @files = grep { /^\Q${package}_$fileversion.orig.tar.\E/ }
230
map { chomp; $_; } # remove newlines
231
`pristine-tar list 2>&1`;
233
system "pristine-tar checkout ../$files[0]";
236
if (my @f = glob "../${package}_$fileversion.orig.tar.*") {
242
open S, "apt-cache showsrc '$package' |";
245
local $/ = ""; # slurp paragraphs
251
foreach my $src (@showsrc) {
252
$src =~ /^Package: (.*)/m or next;
253
next if ($1 ne $package); ; # should never trigger, but who knows
254
$src =~ /^Version: (.*)/m or next;
256
my $srcorigversion = $srcversion;
257
$srcorigversion =~ s/(.*)-.*/$1/; # strip everything from the last dash
259
if ($srcorigversion eq $origversion) { # loop through all matching versions
260
$bestsrcversion = $srcversion;
261
last if ($srcversion eq $version); # break if exact match
265
if ($bestsrcversion) {
266
print "Trying apt-get source $package=$bestsrcversion ...\n";
267
my $t = $tar_only ? '--tar-only' : '';
268
system "cd .. && apt-get source --only-source --download-only $t '$package=$bestsrcversion'";
271
if (my @f = glob "../${package}_$fileversion.orig.tar.*") {
277
if (-f "debian/watch") {
278
print "Trying uscan --download-current-version ...\n";
279
system "uscan --download-current-version --rename\n";
282
if (my @f = glob "../${package}_$fileversion.orig.tar.*") {
286
print "Could not find any location for ${package}_$fileversion.orig.tar.*\n";
290
sub clean_checkout ()
292
# delete all files except debian/, our VCS checkout, and some files
293
# often in VCS outside debian/ even in debian-dir-only repositories
294
opendir DIR, '.' or die "opendir: $!";
296
while (my $file = readdir DIR) {
297
next if ($file eq '.' or $file eq '..');
298
next if ($file eq 'debian');
299
next if ($file =~ /^(\.bzr|\.git|\.hg|\.svn|CVS)$/);
300
if ($file =~ /^(\.bzr(ignore|-builddeb)|\.gitignore|\.hgignore)$/) {
301
print "Notice: not deleting $file (likely to come from VCS checkout)\n";
307
system ('rm', '-rf', @rm);
310
sub unpack_tarball ($)
313
my $tmpdir = File::Temp->newdir(DIR => ".", CLEANUP => 1);
315
print "Unpacking $origtar\n";
318
chdir $tmpdir or die "chdir $tmpdir: $!";
319
system ('tar', 'xf', "../$origtar");
321
print STDERR "tar xf $origtar failed\n";
326
# figure out which directory was created
327
my @dirs = glob "$tmpdir/*/";
329
print STDERR "tar xf $origtar did not create any directory\n";
332
my $directory = $dirs[0];
335
# move all files over, except the debian directory
336
opendir DIR, $directory or die "opendir $directory: $!";
337
foreach my $file (readdir DIR) {
338
if ($file eq 'debian') {
339
system ('rm', '-rf', "$directory/$file");
341
} elsif ($file eq '.' or $file eq '..') {
344
unless (rename "$directory/$file", "$file") {
345
print STDERR "rename $directory/$file $file: $!\n";
362
my $origtar = download_origtar;
363
exit 1 unless ($origtar);
365
if ($unpack eq 'once') {
366
my @files = glob '*'; # ignores dotfiles
367
if (@files == 1) { # this is debian/, we have already opened debian/changelog
368
unpack_tarball ($origtar) or exit 1;
370
} elsif ($unpack eq 'yes') {
372
unpack_tarball ($origtar) or exit 1;