~ubuntu-branches/ubuntu/saucy/devscripts/saucy

« back to all changes in this revision

Viewing changes to scripts/origtargz.pl

  • Committer: Package Import Robot
  • Author(s): Benjamin Drung, Christoph Berg, James McCoy, Dmitry Smirnov, Paul Wise, Benjamin Drung, Cyril Brulebois, Tony Mancill, David Prévot, Josselin Mouette, Raphael Geissert, Regid Ichira, Colin Watson
  • Date: 2013-02-18 21:50:11 UTC
  • mfrom: (10.7.8 squeeze)
  • mto: (10.10.1 sid)
  • mto: This revision was merged to the branch mainline in revision 132.
  • Revision ID: package-import@ubuntu.com-20130218215011-efervwilveqwzzzx
Tags: 2.13.0
[ Christoph Berg ]
* origtargz: New script: fetch the orig tarball of a Debian package from
  various sources, and unpack it
* debcommit: --changelog-info will pass --author and --date for git commits.

[ James McCoy ]
* licensecheck: Recognize MPL 2.0 licenses.  Thanks to Ryan Pavlik for the
  patch.  (Closes: #687664)
* namecheck: Check Apache's projects page for names.  (Closes: #686862)
* debcommit:
  + Drop checks for old dpkg versions and always use the necessary Perl
    modules (Dpkg::Changelog::Parse, Dpkg::Vendor::Ubuntu,
    Dpkg::Changelog::Entry::Debian).
  + Add changelog info support for hg and bzr.
* annotate-output:
  + Handle an incomplete line of output.  (Closes: #695609)
  + Don't treat backslashes in the command's output as an escape.  (Closes:
    #695613)
  + Don't swallow leading whitespace.  (Closes: #695612, LP: #1120917)
* dscverify: Use "gpg --status-fd" to determine if a valid signature is
  found and only use the signed content.  (Closes: #695914)
* wrap-and-sort: Fix repeated word in man page.  (Closes: #696363)

[ Dmitry Smirnov ]
* licensecheck:
  + Remove any regular comments pattern. (Closes: #526698)
  + Improve command line parsing.
  + Fix GPL license version detection bug.
  + Fix BSD-3-clause detection.

[ Paul Wise ]
* checkbashisms: When examining a bash script, indicate the lack of use of
  bashisms.
* uscan:
  + Access GitHub directly instead of using githubredir.debian.net in
    example GitHub watch URL.
  + Add an example watch URL that matches the various file extensions used
    by common archive formats.
  + Add an example watch URL for Google Code projects.

[ Benjamin Drung ]
* Add bashism test cases from Raphael Geissert.
* Add autopkgtest support. (LP: #1073330)
* suspicious-source: Add inode/symlink and image/x-xpmi to whitelisted
  mime-types.
* wrap-and-sort:
  + Put special entries (variables and placeholders) at the end of the list.
  + Sort debian/control*.in files too.
* licensecheck: detect (L)GPL licenses more permissively. Thanks to
  Laurent Rineau for the patch. (Closes: #659231)
* Bump Standards-Version to 3.9.4 (no changes needed).

[ Cyril Brulebois ]
* Don't auto reverse diffs when DEBDIFF_AUTO_VER_SORT is set to yes, and
  when the version in both packages is the same. (Closes: #650732)

[ Tony Mancill ]
* debsnap: Escape the package name when used in regex.  (Closes: #696018)

[ David Prévot ]
* Minor manpages convention fix: do not terminate the SEE ALSO lists with a
  period. (Closes: #696416)
* French translation update.

[ Josselin Mouette ]
* nmudiff: Use dpkg-parsechangelog to fix manual parsing bug (Closes: #700584)

[ Raphael Geissert ]
* checkbashisms:
  + allow -FOO- as heredoc delimiter
  + simplify mixed single/double balanced quotes correctly
  + correct description of 'setvar'
  + detect traps for DEBUG, ERRNO, or RETURN
  + check for incorrect args. to 'exit' (Closes: #687450)
  + fix handling of # characters in quoted strings
  + detect use of $FUNCNAME, $TMOUT, and $TIMEFORMAT
  + detect uses of sleep with anything other than an int.
  + detect the use of the hash utility and $_
  + check for other forms of brace expansion
  + check for use of non-standard tilde expansion
  + check for case modification expansions
  + check for the use of $GLOBIGNORE

[ Regid Ichira ]
* rc-alert: Support using curl as alternative to wget. (Closes: #690024)
* wnpp-alert: Support using curl as alternative to wget. (Closes: #690056)
* wnpp-check: Support using curl as alternative to wget. (Closes: #690059)

[ Colin Watson ]
* debian/control: Mark devscripts Multi-Arch: foreign. (Closes: #694760)
* debchange, debcommit: Set the timestamp of temporary editor files back
  one second, to make modification detection more reliable in the absence
  of subsecond granularity. (Closes: #697923)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/perl
 
2
#
 
3
# origtargz: fetch the orig tarball of a Debian package from various sources,
 
4
# and unpack it
 
5
# Copyright (C) 2012  Christoph Berg <myon@debian.org>
 
6
#
 
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.
 
11
#
 
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.
 
16
#
 
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/>.
 
19
 
 
20
=head1 NAME
 
21
 
 
22
origtargz - fetch the orig tarball of a Debian package from various sources, and unpack it
 
23
 
 
24
=head1 SYNOPSIS
 
25
 
 
26
=over
 
27
 
 
28
=item B<origtargz> [I<OPTIONS>] [B<--unpack>[=B<no>|B<once>|B<yes>]]
 
29
 
 
30
=item B<origtargz> B<--help>
 
31
 
 
32
=back
 
33
 
 
34
=head1 DESCRIPTION
 
35
 
 
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.
 
41
 
 
42
Various download locations are tried:
 
43
 
 
44
=over 4
 
45
 
 
46
=item * First, an existing file is looked for.
 
47
 
 
48
=item * Directories given with B<--path> are searched.
 
49
 
 
50
=item * B<apt-get source> is tried when B<apt-cache showsrc> reports a matching version.
 
51
 
 
52
=item * Finally, B<uscan --download-current-version> is tried.
 
53
 
 
54
=back
 
55
 
 
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).
 
64
 
 
65
The default behavior is to unpack the orig tarball on the first invocation of
 
66
B<origtargz> in a debian-dir-only checkout.
 
67
 
 
68
=head1 NOTES
 
69
 
 
70
Despite B<origtargz> being called "targz", it will work with any compression
 
71
scheme used for the tarball.
 
72
 
 
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
 
76
metadata.
 
77
 
 
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.
 
82
 
 
83
=head1 OPTIONS
 
84
 
 
85
=over
 
86
 
 
87
=item B<-p>, B<--path> I<directory>
 
88
 
 
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.
 
91
 
 
92
=item B<-u>, B<--unpack>[=B<no>|B<once>|B<yes>]
 
93
 
 
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>.
 
98
 
 
99
=over
 
100
 
 
101
=item B<no>
 
102
 
 
103
Do not unpack the orig tarball.
 
104
 
 
105
=item B<once> (default when B<--unpack> is not used)
 
106
 
 
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.
 
109
 
 
110
=item B<yes> (default for B<--unpack> without argument)
 
111
 
 
112
Always unpack the orig tarball.
 
113
 
 
114
=back
 
115
 
 
116
=item B<-d>, B<--download-only>
 
117
 
 
118
Alias for B<--unpack=no>.
 
119
 
 
120
=item B<-t>, B<--tar-only>
 
121
 
 
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.
 
126
 
 
127
=item B<--clean>
 
128
 
 
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.
 
131
 
 
132
=back
 
133
 
 
134
=cut
 
135
 
 
136
#=head1 CONFIGURATION VARIABLES
 
137
#
 
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:
 
143
 
 
144
=head1 SEE ALSO
 
145
 
 
146
B<debcheckout>(1), B<git-import-orig>(1), B<svn-upgrade>(1), B<uupdate>(1)
 
147
 
 
148
=head1 AUTHOR
 
149
 
 
150
B<origtargz> and this manpage have been written by Christoph Berg
 
151
<I<myon@debian.org>>.
 
152
 
 
153
=cut
 
154
 
 
155
# option parsing
 
156
 
 
157
use strict;
 
158
use warnings;
 
159
use File::Temp qw/tempdir/;
 
160
use Getopt::Long qw(:config gnu_getopt);
 
161
use Pod::Usage;
 
162
 
 
163
my @dirs = ();
 
164
my $tar_only = 0;
 
165
my $unpack = 'once'; # default when --unpack is not used
 
166
my $clean = 0;
 
167
 
 
168
GetOptions(
 
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,
 
174
        "clean" => \$clean,
 
175
) or pod2usage({-exitval => 3});
 
176
 
 
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)$/);
 
179
 
 
180
# get package name and version number
 
181
 
 
182
my ($package, $version, $origversion, $fileversion);
 
183
 
 
184
open F, "debian/changelog" or die "debian/changelog: $!\n";
 
185
my $line = <F>;
 
186
close F;
 
187
unless ($line =~ /^(\S+) \((\S+)\)/) {
 
188
        die "could not parse debian/changelog:1: $line";
 
189
}
 
190
($package, $version) = ($1, $2);
 
191
unless ($version =~ /-/) {
 
192
        print "Package with native version number $version, skipping orig.tar.* download\n";
 
193
        exit 0;
 
194
}
 
195
$origversion = $version;
 
196
$origversion =~ s/(.*)-.*/$1/; # strip everything from the last dash
 
197
$fileversion = $origversion;
 
198
$fileversion =~ s/^\d+://; # strip epoch
 
199
 
 
200
# functions
 
201
 
 
202
sub download_origtar ()
 
203
{
 
204
        # look for an existing file
 
205
 
 
206
        if (my @f = glob "../${package}_$fileversion.orig.tar.*") {
 
207
                print "Using existing $f[0]\n";
 
208
                return $f[0];
 
209
        }
 
210
 
 
211
        # try other directories
 
212
 
 
213
        foreach my $dir (@dirs) {
 
214
                $dir =~ s!/$!!;
 
215
 
 
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
 
222
                                die "symlink: $!";
 
223
                        return $f[0];
 
224
                }
 
225
        }
 
226
 
 
227
        # try pristine-tar
 
228
 
 
229
        my @files = grep { /^\Q${package}_$fileversion.orig.tar.\E/ }
 
230
                map { chomp; $_; } # remove newlines
 
231
                `pristine-tar list 2>&1`;
 
232
        if (@files) {
 
233
                system "pristine-tar checkout ../$files[0]";
 
234
        }
 
235
 
 
236
        if (my @f = glob "../${package}_$fileversion.orig.tar.*") {
 
237
                return $f[0];
 
238
        }
 
239
 
 
240
        # try apt-get source
 
241
 
 
242
        open S, "apt-cache showsrc '$package' |";
 
243
        my @showsrc;
 
244
        {
 
245
                local $/ = ""; # slurp paragraphs
 
246
                @showsrc = <S>;
 
247
        }
 
248
        close S;
 
249
 
 
250
        my $bestsrcversion;
 
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;
 
255
                my $srcversion = $1;
 
256
                my $srcorigversion = $srcversion;
 
257
                $srcorigversion =~ s/(.*)-.*/$1/; # strip everything from the last dash
 
258
 
 
259
                if ($srcorigversion eq $origversion) { # loop through all matching versions
 
260
                        $bestsrcversion = $srcversion;
 
261
                        last if ($srcversion eq $version); # break if exact match
 
262
                }
 
263
        }
 
264
 
 
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'";
 
269
        }
 
270
 
 
271
        if (my @f = glob "../${package}_$fileversion.orig.tar.*") {
 
272
                return $f[0];
 
273
        }
 
274
 
 
275
        # try uscan
 
276
 
 
277
        if (-f "debian/watch") {
 
278
                print "Trying uscan --download-current-version ...\n";
 
279
                system "uscan --download-current-version --rename\n";
 
280
        }
 
281
 
 
282
        if (my @f = glob "../${package}_$fileversion.orig.tar.*") {
 
283
                return $f[0];
 
284
        }
 
285
 
 
286
        print "Could not find any location for ${package}_$fileversion.orig.tar.*\n";
 
287
        return undef;
 
288
}
 
289
 
 
290
sub clean_checkout ()
 
291
{
 
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: $!";
 
295
        my @rm;
 
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";
 
302
                        next;
 
303
                }
 
304
                push @rm, $file;
 
305
        }
 
306
        close DIR;
 
307
        system ('rm', '-rf', @rm);
 
308
}
 
309
 
 
310
sub unpack_tarball ($)
 
311
{
 
312
        my $origtar = shift;
 
313
        my $tmpdir = File::Temp->newdir(DIR => ".", CLEANUP => 1);
 
314
 
 
315
        print "Unpacking $origtar\n";
 
316
 
 
317
        # unpack
 
318
        chdir $tmpdir or die "chdir $tmpdir: $!";
 
319
        system ('tar', 'xf', "../$origtar");
 
320
        if ($? >> 8) {
 
321
                print STDERR "tar xf $origtar failed\n";
 
322
                return 0;
 
323
        }
 
324
        chdir '..';
 
325
 
 
326
        # figure out which directory was created
 
327
        my @dirs = glob "$tmpdir/*/";
 
328
        unless (@dirs) {
 
329
                print STDERR "tar xf $origtar did not create any directory\n";
 
330
                return 0;
 
331
        }
 
332
        my $directory = $dirs[0];
 
333
        chop $directory;
 
334
 
 
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");
 
340
                        next;
 
341
                } elsif ($file eq '.' or $file eq '..') {
 
342
                        next;
 
343
                }
 
344
                unless (rename "$directory/$file", "$file") {
 
345
                        print STDERR "rename $directory/$file $file: $!\n";
 
346
                        return 0;
 
347
                }
 
348
        }
 
349
        closedir DIR;
 
350
        rmdir $directory;
 
351
 
 
352
        return 1;
 
353
}
 
354
 
 
355
# main
 
356
 
 
357
if ($clean) {
 
358
        clean_checkout;
 
359
        exit 0;
 
360
}
 
361
 
 
362
my $origtar = download_origtar;
 
363
exit 1 unless ($origtar);
 
364
 
 
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;
 
369
        }
 
370
} elsif ($unpack eq 'yes') {
 
371
        clean_checkout;
 
372
        unpack_tarball ($origtar) or exit 1;
 
373
}
 
374
 
 
375
exit 0;